arweave-account
Version:
Account protocol library on Arweave by Metaweave.xyz
207 lines (206 loc) • 9.75 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const arweave_1 = __importDefault(require("arweave"));
const ardb_1 = __importDefault(require("ardb"));
const Cache_1 = __importDefault(require("./Cache"));
const data_1 = __importDefault(require("./data"));
const config_1 = __importDefault(require("./config"));
const constants_1 = require("./constants");
class Account {
constructor({ cacheIsActivated = true, cacheSize = 100, cacheTime = 60000, gateway = {
host: 'arweave.net',
port: 443,
protocol: 'https',
timeout: 20000,
logging: false,
}, defaultAvatarUri = "ar://OrG-ZG2WN3wdcwvpjz1ihPe4MI24QBJUpsJGIdL85wA", defaultBannerUri = "ar://a0ieiziq2JkYhWamlrUCHxrGYnHWUAMcONxRmfkWt-k" } = {}) {
this.walletAddr = null;
this.debug = {
resetCache: () => {
var _a;
(_a = this.cache) === null || _a === void 0 ? void 0 : _a.reset();
},
printCache: () => {
var _a;
const now = new Date();
// tslint:disable-next-line
console.log(` > Cache content at ${now.toISOString().replace(/T/, ' ').replace(/\..+/, '')}\n`);
// tslint:disable-next-line
console.log((_a = this.cache) === null || _a === void 0 ? void 0 : _a.dump());
},
};
new config_1.default(gateway, defaultAvatarUri, defaultBannerUri);
this.arweave = arweave_1.default.init(gateway);
this.ardb = new ardb_1.default(this.arweave);
if (cacheIsActivated) {
if (typeof window !== 'undefined') {
this.cache = new Cache_1.default('web', cacheSize, cacheTime);
}
else
this.cache = new Cache_1.default('node', cacheSize, cacheTime);
}
else
this.cache = null;
}
connect(jwk = 'use_wallet') {
return __awaiter(this, void 0, void 0, function* () {
this.walletAddr = yield this.arweave.wallets.getAddress(jwk);
});
}
updateProfile(profile, tags) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
if (!this.walletAddr)
throw Error('Method connect() should be called before updateProfile().');
if (!data_1.default.isProfile(profile))
throw Error(`Object "${JSON.stringify(profile)}" doesn't match with the shape of a T_profile object.\nTypescript tip: import { T_profile } from 'arweave-account'`);
const encodedAccount = data_1.default.encodeForStorage(profile);
const data = JSON.stringify(encodedAccount);
const tx = yield this.arweave.createTransaction({ data });
tx.addTag('Protocol-Name', constants_1.PROTOCOL_NAMES[constants_1.PROTOCOL_NAMES.length - 1]);
tx.addTag('handle', profile.handleName);
if (tags)
tags.filter((tag) => tag.name !== 'Protocol-Name' && tag.name !== 'handle').map((tag) => tx.addTag(tag.name, tag.value));
let result = tx;
try {
if (window.arweaveWallet) {
// @ts-ignore try bundlr first
result = yield window.arweaveWallet.dispatch(tx);
}
else
throw 'no window.arweaveWallet';
}
catch (e) {
try {
yield this.arweave.transactions.sign(tx);
yield this.arweave.transactions.post(tx);
}
catch (e) {
throw e;
}
}
if (encodedAccount) {
const account = data_1.default.decode(result.id, this.walletAddr, encodedAccount);
(_a = this.cache) === null || _a === void 0 ? void 0 : _a.hydrate(account);
}
return result;
});
}
get(addr) {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
addr = addr.trim();
if (!/^[a-zA-Z0-9\-_]{43}$/.test(addr))
throw 'Invalid wallet address argument';
const cacheResponse = (_a = this.cache) === null || _a === void 0 ? void 0 : _a.get(addr);
if (cacheResponse)
return cacheResponse;
else {
const tx = yield this.ardb
.search('transactions')
.exclude('anchor')
.tag('Protocol-Name', constants_1.PROTOCOL_NAMES)
.from(addr)
.limit(1)
.find();
const txid = tx[0] ? tx[0].id : null;
try {
const { data } = txid ? yield this.arweave.api.get(txid) : { data: null };
const account = data_1.default.decode(txid, addr, data);
(_b = this.cache) === null || _b === void 0 ? void 0 : _b.hydrate(account);
return account;
}
catch (e) {
// if JSON.parse(data) throw an error because data is not a valid JSON
return data_1.default.getDefaultAccount(addr);
}
}
});
}
search(handle) {
return __awaiter(this, void 0, void 0, function* () {
const txs = yield this.ardb
.search('transactions')
.exclude('anchor')
.tag('Protocol-Name', constants_1.PROTOCOL_NAMES)
.tag('handle', handle)
.limit(100)
.find();
const formattedAccounts = yield Promise.all(txs.map((tx) => __awaiter(this, void 0, void 0, function* () {
const txid = tx.id;
const addr = 'owner' in tx ? tx.owner.address : 'anonymous';
try {
const { data } = yield this.arweave.api.get(txid);
const accountObj = data_1.default.decode(txid, addr, data);
return accountObj;
}
catch (e) {
// if uploaded JSON data is not a valid JSON
return data_1.default.getDefaultAccount(addr);
}
})));
const accounts = formattedAccounts.filter((v, i, a) => v !== null &&
// remove address duplicates: https://stackoverflow.com/a/56757215
a.findIndex((t) => (t === null || t === void 0 ? void 0 : t.addr) === (v === null || v === void 0 ? void 0 : v.addr)) === i);
/*
* It appears that some accounts found are not the latest txid related to it.
* Until this bug is solved the caching hydration is disabled.
*/
// accounts.forEach((ac) => this.cache?.hydrate(ac.addr, ac));
return accounts;
});
}
find(uniqueHandle) {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
uniqueHandle = uniqueHandle.trim();
// check if format is handle#xxxxxx
if (!/^(.+)#[a-zA-Z0-9\-\_]{6}$/.test(uniqueHandle))
return null;
const cacheResponse = (_a = this.cache) === null || _a === void 0 ? void 0 : _a.find(uniqueHandle);
if (cacheResponse !== undefined)
return cacheResponse;
else {
const txs = yield this.ardb
.search('transactions')
.exclude('anchor')
.tag('Protocol-Name', constants_1.PROTOCOL_NAMES)
.tag('handle', uniqueHandle.slice(0, -7))
.limit(100)
.find();
const formattedAccounts = yield Promise.all(txs.map((tx) => __awaiter(this, void 0, void 0, function* () {
const txid = tx.id;
const addr = 'owner' in tx ? tx.owner.address : 'anonymous';
try {
const { data } = yield this.arweave.api.get(txid);
return data_1.default.decode(txid, addr, data);
}
catch (e) {
// if JSON.parse(data) throw an error because data is not a valid JSON
return data_1.default.getDefaultAccount(addr);
}
})));
const accounts = formattedAccounts.filter((e) => e !== undefined);
const account = accounts.find((ac) => ac.handle.includes(uniqueHandle));
if (account) {
(_b = this.cache) === null || _b === void 0 ? void 0 : _b.hydrate(account);
return account;
}
else
return null;
}
});
}
}
exports.default = Account;