godprotocol
Version:
A distributed computing environment for Web 4.0 — integrating AI, decentralisation, and virtual computation.
198 lines (165 loc) • 4.77 kB
JavaScript
import { post_request } from "../utils/services.js";
import {
encrypt,
decrypt,
} from "@godprotocol/repositories/utils/cryptography.js";
class Oracle_client {
constructor(server, options = {}) {
this.server = server;
this.manager_key = options.manager_key;
this.repo_cache = new Object();
this.repos = new Array();
}
add_repo = async (repo) => {
let repo_ = await this.cloth_repo(repo.repo);
this.repos.push(repo_);
await this.fetch({
method: "add_repo",
args: { repo: encrypt(JSON.stringify(repo), this.manager_key) },
});
return repo_;
};
write_local = async (path, content, options) => {
if (this.local) {
await this.local.write(path, content, options);
}
};
read_local = async (path, options) => {
if (this.local) {
let content = await this.local.read(path, options);
return content;
}
return null;
};
write = async (path, content, options) => {
await this.fetch({
method: Array.isArray(content) ? "write_bulk" : "write",
args: { path, content, options },
});
};
read = async (path, options = {}) => {
let repo = this.repo_cache[path],
content;
if (repo) {
if (options.decrypt === true) options.decrypt = this.manager_key;
content = await repo.read(path, { decrypt: options.decrypt });
}
if (!content) {
let response = await this.fetch({
method: "read",
args: { path, options },
});
content = response && response.content;
if (content) {
repo = response.repo;
repo = await this.cloth_repo(
JSON.parse(decrypt(repo, this.manager_key))
);
if (repo) this.repo_cache[path] = repo;
}
}
return content;
};
server_match = (s1, s2) => s1.hostname === s2.hostname && s1.port === s2.port;
get_servers = async (account) => {
let addr = `${account}/.servers`;
let servers = await this.read(addr);
servers = servers ? JSON.parse(servers) : [];
return servers;
};
update_servers = async (account) => {
let servers = await this.get_servers(account);
if (!servers.find((s) => this.server_match(s, this.client))) {
servers.push(this.client);
await this.write(addr, JSON.stringify(servers));
}
return servers;
};
fetch = async (payload) => {
let auth_token = await this.get_auth_token();
let headers;
if (payload.method !== "authenticate" && !auth_token) {
await this.sync(this.client);
} else if (payload.method !== "authenticate") {
headers = {
authorisation: auth_token,
};
}
try {
let resp = await post_request({
options: {
...this.server,
path: `/oracle/${payload.method}`,
headers,
},
data: JSON.stringify(payload.args),
});
if (resp.error === "Token expired") {
await this.set_auth_token(null);
await this.sync(this.client);
resp = await this.fetch(payload);
}
return resp || null;
} catch (e) {
console.warn("fetch error:", e.message || e);
return null;
}
};
sync = async (client, Repos, local) => {
this.client = client;
if (Repos) this.Repos = new Repos();
if (local) this.local = await this.Repos.cloth_repo(local.repo);
await this.get_auth_token();
if (this.auth_token) {
if (local) {
this.local = await this.add_repo(local);
return;
}
}
let auth = await this.fetch({
method: "authenticate",
args: {
client: this.client,
key: encrypt(this.manager_key, this.manager_key),
},
});
if (!auth) return;
if (auth.token) {
if (local) {
this.auth_token = auth.token;
this.local = await this.add_repo(local);
}
await this.set_auth_token(auth.token);
}
};
get_auth_token = async () => {
let token = this.auth_token;
if (!token) {
token = await this.read_local(this.token_addr, {
decrypt: this.manager_key,
});
if (token && token.expired) token = null;
if (token) {
token = JSON.parse(token);
this.auth_token = token.token;
this.client = token.client;
}
}
return this.auth_token;
};
token_addr = `.clients/sign`;
set_auth_token = async (token) => {
let obj = { client: this.client, token };
if (!token) {
this.auth_token = null;
obj.expired = true;
}
await this.write_local(this.token_addr, JSON.stringify(obj), {
encrypt: this.manager_key,
});
};
cloth_repo = async (repo) => {
return this.Repos && (await this.Repos.cloth_repo(repo));
};
}
export default Oracle_client;