@ethersphere/swarm-cli
Version:
CLI tool for Bee
173 lines (172 loc) • 8.54 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Print = void 0;
const bee_js_1 = require("@ethersphere/bee-js");
const cafe_utility_1 = require("cafe-utility");
const ethereumjs_wallet_1 = __importDefault(require("ethereumjs-wallet"));
const furious_commander_1 = require("furious-commander");
const process_1 = require("process");
const identity_1 = require("../../service/identity");
const utils_1 = require("../../utils");
const spinner_1 = require("../../utils/spinner");
const text_1 = require("../../utils/text");
const feed_command_1 = require("./feed-command");
class Print extends feed_command_1.FeedCommand {
constructor() {
super(...arguments);
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: 'print'
});
Object.defineProperty(this, "description", {
enumerable: true,
configurable: true,
writable: true,
value: 'Print feed'
});
Object.defineProperty(this, "address", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "list", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
}
async run() {
super.init();
if (!this.address) {
const wallet = await this.getWallet();
this.address = wallet.getAddressString();
}
const topic = this.topic ? new bee_js_1.Topic(this.topic) : bee_js_1.Topic.fromString(this.topicString);
// construct the feed manifest chunk
const body = cafe_utility_1.Binary.concatBytes(new Uint8Array(32), new Uint8Array([
0x57, 0x68, 0xb3, 0xb6, 0xa7, 0xdb, 0x56, 0xd2, 0x1d, 0x1a, 0xbf, 0xf4, 0x0d, 0x41, 0xce, 0xbf, 0xc8, 0x34,
0x48, 0xfe, 0xd8, 0xd7, 0xe9, 0xb0, 0x6e, 0xc0, 0xd3, 0xb0, 0x73, 0xf2, 0x8f, 0x20,
]), new Uint8Array(37), new Uint8Array([0x80]), new Uint8Array(26), new Uint8Array([0x12, 0x01, 0x2f]), new Uint8Array(29), new Uint8Array([
0x85, 0x04, 0xf2, 0xa1, 0x07, 0xca, 0x94, 0x0b, 0xea, 0xfc, 0x4c, 0xe2, 0xf6, 0xc9, 0xa9, 0xf0, 0x96, 0x8c,
0x62, 0xa5, 0xb5, 0x89, 0x3f, 0xf0, 0xe4, 0xe1, 0xe2, 0x98, 0x30, 0x48, 0xd2, 0x76, 0x00, 0xbe,
]), new TextEncoder().encode(`{"swarm-feed-owner":"${this.address.replace('0x', '')}","swarm-feed-topic":"${topic}","swarm-feed-type":"Sequence"}`), new Uint8Array(12).fill(0x0a));
const root = (await bee_js_1.MerkleTree.root(body)).hash();
const manifest = cafe_utility_1.Binary.uint8ArrayToHex(root);
this.console.quiet(manifest);
if (this.quiet) {
return;
}
this.console.log((0, text_1.createKeyValue)('Feed Manifest URL', `${this.bee.url}/bzz/${manifest}/`));
const spinner = (0, spinner_1.createSpinner)(`Looking up feed topic ${topic}`);
spinner.start();
try {
const addressString = this.address || (await this.getAddressString());
const reader = this.bee.makeFeedReader(topic, addressString);
const { payload, feedIndex, feedIndexNext } = await reader.download();
// TODO: verify this
const reference = payload;
spinner.stop();
this.console.verbose((0, text_1.createKeyValue)('Chunk Reference', reference.toHex()));
this.console.verbose((0, text_1.createKeyValue)('Chunk Reference URL', `${this.bee.url}/bzz/${reference}/`));
this.console.verbose((0, text_1.createKeyValue)('Feed Index', feedIndex.toBigInt().toString()));
this.console.verbose((0, text_1.createKeyValue)('Next Index', feedIndexNext?.toBigInt().toString() ?? 'N/A'));
this.console.verbose((0, text_1.createKeyValue)('Feed Manifest', manifest));
this.console.log((0, text_1.createKeyValue)('Topic', `${topic}`));
const numberOfUpdates = feedIndex.toBigInt() + BigInt(1);
this.console.log((0, text_1.createKeyValue)('Number of Updates', numberOfUpdates.toString(0)));
if (this.list) {
for (let i = 0; i < numberOfUpdates; i++) {
const indexBytes = cafe_utility_1.Binary.numberToUint64(BigInt(i), 'BE');
const identifier = cafe_utility_1.Binary.keccak256(cafe_utility_1.Binary.concatBytes(topic.toUint8Array(), indexBytes));
const owner = cafe_utility_1.Binary.hexToUint8Array(this.address);
const soc = cafe_utility_1.Binary.uint8ArrayToHex(cafe_utility_1.Binary.keccak256(cafe_utility_1.Binary.concatBytes(identifier, owner)));
const chunk = await this.bee.downloadChunk(soc);
// span + identifier + signature + span
const cac = cafe_utility_1.Binary.uint8ArrayToHex(chunk.slice(8 + 32 + 65 + 8, 8 + 32 + 65 + 32 + 8));
this.console.log('');
this.console.log((0, text_1.createKeyValue)(`Update ${i}`, cac));
this.console.log(`${this.bee.url}/bzz/${cac}/`);
}
}
else {
this.console.log('Run with --list to see all updates');
}
}
catch (error) {
spinner.stop();
const message = (0, utils_1.getFieldOrNull)(error, 'message');
throw Error(`Feed topic lookup error: ${message || 'unknown'}`);
}
finally {
spinner.stop();
}
}
async getAddressString() {
const identity = this.commandConfig.config.identities[this.identity];
if (!identity) {
this.console.error('No such identity');
(0, process_1.exit)(1);
}
if (identity) {
if (this.password) {
const wallet = await this.getWallet();
return wallet.getAddressString();
}
else {
return this.getAddressStringFromIdentity(identity);
}
}
return this.identity;
}
getAddressStringFromIdentity(identity) {
const { wallet, identityType } = identity;
if ((0, identity_1.isV3Wallet)(wallet, identityType)) {
if (!wallet.address) {
this.console.error('No address in V3 wallet, please provide password so it can be decrypted.');
(0, process_1.exit)(1);
}
return wallet.address;
}
else if ((0, identity_1.isSimpleWallet)(wallet, identityType)) {
const privateKey = wallet.privateKey.replace('0x', '');
const ethereumWallet = ethereumjs_wallet_1.default.fromPrivateKey(Buffer.from(privateKey, 'hex'));
return ethereumWallet.getAddressString();
}
else {
this.console.error('Address type is not supported.');
(0, process_1.exit)(1);
}
}
}
__decorate([
(0, furious_commander_1.Option)({
key: 'address',
type: 'hex-string',
alias: 'a',
description: 'Public Ethereum Address for feed lookup',
required: true,
conflicts: 'identity',
}),
__metadata("design:type", String)
], Print.prototype, "address", void 0);
__decorate([
(0, furious_commander_1.Option)({ key: 'list', type: 'boolean', description: 'List all updates' }),
__metadata("design:type", Boolean)
], Print.prototype, "list", void 0);
exports.Print = Print;