@nfps.dev/runtime
Version:
Runtime library for NFPs
149 lines • 5.72 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.boot = exports.nfp_attr = exports.nfp_tags = void 0;
const belt_1 = require("@blake.regalia/belt");
const neutrino_1 = require("@solar-republic/neutrino");
const connectivity_1 = require("./connectivity");
const constants_1 = require("./constants");
const dom_1 = require("./dom");
let k_contract;
let a_location;
let z_auth;
let si_storage_auth;
let xc_busy = 0;
const nfp_tags = (si_tag) => document.getElementsByTagNameNS(constants_1.P_NS_NFP, si_tag);
exports.nfp_tags = nfp_tags;
const nfp_attr = (dm_element, si_attr) => dm_element.getAttributeNS(constants_1.P_NS_NFP, si_attr);
exports.nfp_attr = nfp_attr;
const import_query_key_prompt = () => {
// prompt for key
const sx_import = prompt(`NFP requires either (1) the owner's viewing key or (2) a query permit signed by the token owner; paste one here to unlock\n\nPermits should be JSON in shape of '{"params":..,"signature":..}'`)?.trim();
// something was entered
if (sx_import) {
// attempt to parse as json
let h_input;
try {
h_input = JSON.parse(sx_import);
}
catch (e_parse) { }
// parsed as JSON object; use as permit
if ('object' === typeof h_input) {
z_auth = h_input;
}
// treat text as viewing key
else {
z_auth = [sx_import];
}
}
};
const hydrate_nfp = async () => {
// find scripts
const a_srcs = Array.from((0, exports.nfp_tags)('script'))
.map(dm => [dm, (0, exports.nfp_attr)(dm, 'src')?.split('?')]);
const a_load = [];
for (const [dm_element, [si_package, sx_params]] of a_srcs) {
const dm_script = await (0, connectivity_1.load_script)(si_package, (0, belt_1.ofe)(new URLSearchParams(sx_params || '').entries()), k_contract, a_location, z_auth);
// auth worked, save it to local storage
(0, dom_1.ls_write_json)(si_storage_auth, z_auth);
// replace script
if (dm_script) {
a_load.push(() => dm_element.replaceWith(dm_script));
}
// fail
else {
return;
}
}
return () => a_load.map(f => f());
};
const resolve_permit = async () => {
// storage item key
si_storage_auth = a_location.join(':') + ':auth';
// check local storage for auth
z_auth ||= (0, dom_1.ls_read_json)(si_storage_auth);
// use prompt as fallback
if (!z_auth)
import_query_key_prompt();
// something was loaded, hydrate; query succeeded
if (z_auth) {
return await hydrate_nfp();
}
};
const boot = async () => {
// do not boot while loading
if (xc_busy)
return;
// select the first metadata tag
const dm_metadata = document.querySelector(':root>metadata');
if (dm_metadata) {
// first nfp:web tag
const dm_web = (0, exports.nfp_tags)('web')[0];
// first nfp:self tag
const dm_self = (0, exports.nfp_tags)('self')[0];
// missing requisite tag(s)
if (!dm_web || !dm_self)
throw new Error('Missing requisite NFP tags');
// parse lcds attribute
const a_lcds = (0, exports.nfp_attr)(dm_web, 'lcds')?.split(',');
if (!a_lcds?.length)
throw new Error('Missing nfp:lcds attribute');
// destructure nfp:self attribute values
a_location = ['chain', 'contract', 'token']
.map(si_attr => (0, exports.nfp_attr)(dm_self, si_attr));
// auth is baked into contract
const dm_auth = (0, exports.nfp_tags)('auth')[0];
if (dm_auth && !z_auth) {
const sh_vk = (0, exports.nfp_attr)(dm_auth, 'vk');
if (sh_vk) {
z_auth = [sh_vk, (0, exports.nfp_attr)(dm_auth, 'addr')];
}
}
// // secret via localStorage
// for(const dm_secret of nfp_tags('secret')) {
// const p_comc = nfp_attr(dm_secret, 'comc');
// const sh_key = nfp_attr(dm_secret, 'key');
// if(!p_comc || !sh_key) continue;
// const dm_portal = await comcPortal(p_comc as HttpsUrl, document.documentElement);
// const k_comc = await comcClient(dm_portal);
// await ({
// async auth() {
// z_auth = await k_comc.post(XC_CMD_FETCH_DATA, [sh_key]) as AuthSecret;
// },
// } as Dict<() => Promise<void>>)[nfp_attr(dm_secret, 'context')+'']?.();
// // discard portal
// dm_portal.remove();
// }
// set busy state
xc_busy = 1;
// try each endpoint in order
for (const p_lcd of a_lcds) {
try {
// attempt to instantiate contract
k_contract = await (0, neutrino_1.SecretContract)(p_lcd, a_location[1]);
// free
xc_busy = 0;
// done
let f_inject;
// eslint-disable-next-line @typescript-eslint/no-extra-parens
if ((f_inject = await resolve_permit())) {
// return boot info
return [
f_inject,
a_location,
k_contract.lcd,
k_contract,
z_auth,
];
}
}
catch (e_query) {
// free
xc_busy = 0;
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
console.warn(`Endpoint offline: ${p_lcd}; ${e_query.stack}`);
}
}
}
};
exports.boot = boot;
//# sourceMappingURL=boot.js.map