reorganizing because zx needs to feel special

This commit is contained in:
2022-10-05 08:22:45 -06:00
parent 822ffa6c94
commit d1b40247be
84 changed files with 1 additions and 1 deletions
+96
View File
@@ -0,0 +1,96 @@
/*******************************************************************
** Compiler API
**
** The manner in which this module is laid out differs meaningfully
** from the `ae_node` module.
**
** - ae_node basically exposes a subset of the node interface as
** functions. It only black-boxes away the networking aspects.
**
** - part of the reason for this is that the data structures that get
** sent to the node tend to be pretty involved (lots of fields)
**
** - in general, the node interface is significantly more complicated
** than the compiler interface
**
** - by contrast, the data structures that get sent to the compiler
** tend to be pretty simple and only have a small number of fields
**
** - the manner in which this manifests is that ae_node functions
** tend to have a weird esoteric data structure as the input,
** because otherwise there would be too many parameters.
**
** here, there are few parameters, and they are passed directly
**
** - in general, the compiler has fewer things it can do, and the
** things it does tend to depend on less information. so this
** interface is significantly simpler than the node interface
*******************************************************************/
import * as net from './net.js';
const URL_COMPILER = 'https://compiler.aepps.com';
// endpoints
const EPT_CompileContract = URL_COMPILER + '/compile';
const EPT_EncodeCalldata = URL_COMPILER + '/encode-calldata';
//-------------------------------------------------------------------
// HELPERS
//-------------------------------------------------------------------
// make a CompileOpts data structure
function
compile_options(filename: string)
: object
{
return {"backend" : "fate",
"file_system" : {},
"src_file" : filename};
}
//-------------------------------------------------------------------
// API CALLS
//-------------------------------------------------------------------
// send back compile response
async function
CompileContract(code : string,
filename : string)
: Promise<Response>
{
let send_obj =
{"code" : code,
"options" : compile_options(filename)};
let response = await net.post_json_response(EPT_CompileContract, send_obj);
return response;
}
async function
EncodeCalldata(code : string,
filename : string,
function_name : string,
function_args : Array<string>)
: Promise<Response>
{
let send_obj =
{"source" : code,
"options" : compile_options(filename),
"function" : function_name,
"arguments" : function_args};
let response = await net.post_json_response(EPT_EncodeCalldata, send_obj);
return response;
}
export {
CompileContract,
EncodeCalldata
}
+272
View File
@@ -0,0 +1,272 @@
/********************************************************************
** Node API: functions for talking to an Aeternity node
**
** In the future, everything that this module does will be replaced
** by the backend.
**
** Functions should be sorted in alphabetical order.
**
** Names are what they are in the documentation
**
** Useful links:
**
** - HTML API docs : https://api-docs.aeternity.io/
** - YAML API docs : https://github.com/aeternity/aeternity/blob/master/apps/aehttp/priv/swagger.yaml
**
********************************************************************/
import * as net from './net.js'
import * as ae_compiler from './ae_compiler.js'
//-------------------------------------------------------------------
// CONSTANTS
//-------------------------------------------------------------------
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";
//-------------------------------------------------------------------
// CANONICAL TYPES ("MODELS") FROM THE DOCUMENTATION
//
// All of these names are as given in the documentation except `Error`
// (which is a reserve term in JS), renamed to `ErrorReason`
//-------------------------------------------------------------------
// Error
//
// Docs: https://api-docs.aeternity.io/#/definitions/Error
// Docs: https://github.com/aeternity/aeternity/blob/v6.4.0/apps/aehttp/priv/swagger.yaml#L3168-L3172
type ErrorReason = {reason: string};
type Tx = {tx: string};
//-------------------------------------------------------------------
// FUNCTIONS
//
// The names here follow their names in the documentation
//-------------------------------------------------------------------
//-------------------------------------------------------------------
// GetAccountNextNonce: /accounts/{pubkey}/next-nonce
//
// Docs: https://api-docs.aeternity.io/#/account/GetAccountNextNonce
//
// > Get an account's next nonce; This is computed according to
// > whatever is the current account nonce and what transactions are
// > currently present in the transaction pool
//-------------------------------------------------------------------
type GetAccountNextNonce_params = {pubkey : string,
strategy? : "max" | "continuity"};
type GetAccountNextNonce_ret = {next_nonce: string};
async function
GetAccountNextNonce(endpoint_url : string,
params : GetAccountNextNonce_params)
: Promise< GetAccountNextNonce_ret
| ErrorReason>
{
let pubkey = params.pubkey;
let url = `${endpoint_url}/accounts/${pubkey}/next-nonce`;
// if the "strategy" field is present, add it as a ?strategy=x
// option
//
// note if the field is absent from `params`, then
// `params.strategy` will be `undefined`, which in js whacko
// world is "falsy"
let strategy = params.strategy;
if (strategy)
{
let addon = `?strategy=${strategy}`;
url += addon;
}
// irrespective of the response code, this is what we return
// so branching is gay
let ret = await net.get_json(url);
return ret;
}
//-------------------------------------------------------------------
// PostContractCreate
//
// Docs: https://api-docs.aeternity.io/#/contract/PostContractCreate
//-------------------------------------------------------------------
// > Get a contract_create transaction object
type ContractCreateTx = {owner_id : string,
nonce? : number,
code : string,
vm_version : number,
abi_version : number,
deposit : number,
amount : number,
gas : number,
gas_price : number,
fee : number,
ttl? : number,
call_data : string};
async function
PostContractCreate(endpoint_url : string,
body_obj : ContractCreateTx)
: Promise<Response>
{
// console.log('body_obj', body_obj);
let url = `${endpoint_url}/debug/contracts/create`;
let ret = await net.post_json_response(url, body_obj);
return ret;
}
async function
create_contract(whoami : string,
code : string,
filename : string,
init_args : Array<string>)
: Promise<Response>
{
let code_resp = await ae_compiler.CompileContract(code, filename);
let code_json = await code_resp.json();
let bytecode = code_json.bytecode;
let calldata_resp = await ae_compiler.EncodeCalldata(code, filename, "init", init_args);
// assert(calldata_resp.ok);
let calldata_json = await calldata_resp.json();
let calldata = calldata_json.calldata;
let cctx: ContractCreateTx =
{owner_id : whoami,
code : bytecode,
vm_version : 7,
abi_version : 3,
deposit : 0,
amount : 0,
gas : 25000,
gas_price : 1*MIN_GAS_PRICE,
fee : 1*MIN_CONTRACT_FEE,
call_data : calldata};
let ret = await PostContractCreate(URL_TESTNET, cctx);
return ret;
}
//-------------------------------------------------------------------
// PostSpend: /debug/transactions/spend
//
// Docs:
// - Input type : https://api-docs.aeternity.io/#/definitions/SpendTx
// - Return type : https://api-docs.aeternity.io/#/definitions/Tx
// - Function : https://api-docs.aeternity.io/#/transaction/PostSpend
//
// > Get a spend transaction object
//-------------------------------------------------------------------
//-------------------------------------------------------------------
// SpendTx
//
// Docs: https://api-docs.aeternity.io/#/definitions/SpendTx
// Docs: https://github.com/aeternity/aeternity/blob/v6.4.0/apps/aehttp/priv/swagger.yaml#L2187-L2209
//-------------------------------------------------------------------
type SpendTx =
{recipient_id : string,
amount : number,
fee : number,
ttl? : number,
sender_id : string,
nonce? : number,
payload : string};
async function
PostSpend(endpoint_url : string,
body_obj : SpendTx)
: Promise<Tx | ErrorReason>
{
let url = `${endpoint_url}/debug/transactions/spend`;
let ret = await net.post_json(url, body_obj);
return ret;
}
//-------------------------------------------------------------------
// PostTransaction
//
// Docs: https://api-docs.aeternity.io/#/contract/PostTransaction
//
// > Post a new transaction
//-------------------------------------------------------------------
async function
PostTransaction(endpoint_url : string,
body_obj : Tx)
: Promise<Response>
{
// console.log('body_obj', body_obj);
let url = `${endpoint_url}/transactions`;
let ret = await net.post_json_response(url, body_obj);
return ret;
}
//-------------------------------------------------------------------
// GetTransactionInfoByHash
//
// Docs: https://api-docs.aeternity.io/#/contract/GetTransactionInfoByHash
//-------------------------------------------------------------------
async function
GetTransactionInfoByHash(endpoint_url : string,
hash : string)
: Promise<Response>
{
// console.log('body_obj', body_obj);
let url = `${endpoint_url}/transactions/${hash}/info`;
let ret = await net.get_json_response(url);
return ret;
}
//-------------------------------------------------------------------
// EXPORTS
//-------------------------------------------------------------------
// type exports
export type {
ErrorReason,
Tx,
SpendTx,
ContractCreateTx
};
export {
GetAccountNextNonce,
PostContractCreate,
create_contract,
PostSpend,
PostTransaction
};
+85
View File
@@ -0,0 +1,85 @@
//-------------------------------------------------------------------
// Common networking functions
//
// Mozilla fetch docs : https://developer.mozilla.org/en-US/docs/Web/API/fetch
//-------------------------------------------------------------------
/* pf = pretty format
*/
function pf(x : any) : string
{
return JSON.stringify(x, undefined, 4);
}
//-------------------------------------------------------------------
// FUNCTIONS
//-------------------------------------------------------------------
// GET request with return type of JSON
async function
get_json(url: string)
: Promise<any>
{
let response = await fetch(url);
let ret = await response.json();
return ret;
}
// GET request with return type of JSON
async function
get_json_response(url: string)
: Promise<Response>
{
let response = await fetch(url);
//let ret = await response.json();
return response;
}
// POST request with content type of json and return type of JSON
async function
post_json(url : string,
body_obj : any)
: Promise<any>
{
let body_str = pf(body_obj);
let req_opts = {method : 'POST',
body : body_str,
headers : {"Content-Type": "application/json"}};
let response = await fetch(url, req_opts);
let ret = await response.json();
return ret;
}
async function
post_json_response(url : string,
body_obj : any)
: Promise<Response>
{
let body_str = pf(body_obj);
let req_opts = {method : 'POST',
body : body_str,
headers : {"Content-Type": "application/json"}};
let response = await fetch(url, req_opts);
return response;
}
//-------------------------------------------------------------------
// EXPORTS
//-------------------------------------------------------------------
export {
get_json,
get_json_response,
post_json,
post_json_response
}