UNPKG

@ethersphere/swarm-cli

Version:
173 lines (172 loc) 8.54 kB
"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;