UNPKG

ton3-core

Version:
167 lines 5.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Address = void 0; const checksum_1 = require("./utils/checksum"); const helpers_1 = require("./utils/helpers"); const FLAG_BOUNCEABLE = 0x11; const FLAG_NON_BOUNCEABLE = 0x51; const FLAG_TEST_ONLY = 0x80; class Address { constructor(address, options) { const isAddress = Address.isAddress(address); const isEncoded = Address.isEncoded(address); const isRaw = Address.isRaw(address); let result; switch (true) { case isAddress: result = Address.parseAddress(address); break; case isEncoded: result = Address.parseEncoded(address); break; case isRaw: result = Address.parseRaw(address); break; default: result = null; break; } if (result === null) { throw new Error('Address: can\'t parse address. Unknown type.'); } const { workchain = result.workchain, bounceable = result.bounceable, testOnly = result.testOnly } = options || {}; this._hash = result.hash; this._workchain = workchain; this._bounceable = bounceable; this._testOnly = testOnly; } get hash() { return new Uint8Array(this._hash); } get workchain() { return this._workchain; } get bounceable() { return this._bounceable; } get testOnly() { return this._testOnly; } static isEncoded(address) { const re = /^([a-zA-Z0-9_-]{48}|[a-zA-Z0-9\/\+]{48})$/; return typeof address === 'string' && re.test(address); } static isRaw(address) { const re = /^-?[0-9]:[a-zA-Z0-9]{64}$/; return typeof address === 'string' && re.test(address); } static parseEncoded(value) { const base64 = value.replace(/-/g, '+').replace(/_/g, '/'); const bytes = (0, helpers_1.base64ToBytes)(base64); const data = Array.from(bytes); const address = data.splice(0, 34); const checksum = data.splice(0, 2); const crc = (0, checksum_1.crc16BytesBe)(address); if (!(0, helpers_1.bytesCompare)(crc, checksum)) { throw new Error('Address: can\'t parse address. Wrong checksum.'); } const { buffer } = new Uint8Array(address.splice(0, 2)); const view = new DataView(buffer); const tag = view.getUint8(0); const workchain = view.getInt8(1); const hash = new Uint8Array(address.splice(0, 32)); const { bounceable, testOnly } = Address.decodeTag(tag); return { bounceable, testOnly, workchain, hash }; } static parseAddress(value) { const { workchain, bounceable, testOnly } = value; const hash = new Uint8Array(value.hash); return { bounceable, testOnly, workchain, hash }; } static parseRaw(value) { const data = value.split(':'); const workchain = parseInt(data[0], 10); const hash = (0, helpers_1.hexToBytes)(data[1]); const bounceable = false; const testOnly = false; return { bounceable, testOnly, workchain, hash }; } static encodeTag(options) { const { bounceable, testOnly } = options; const tag = bounceable ? FLAG_BOUNCEABLE : FLAG_NON_BOUNCEABLE; return testOnly ? (tag | FLAG_TEST_ONLY) : tag; } static decodeTag(tag) { let data = tag; const testOnly = (data & FLAG_TEST_ONLY) !== 0; if (testOnly) { data ^= FLAG_TEST_ONLY; } if (![FLAG_BOUNCEABLE, FLAG_NON_BOUNCEABLE].includes(data)) { throw new Error('Address: bad address tag.'); } const bounceable = data === FLAG_BOUNCEABLE; return { bounceable, testOnly }; } eq(address) { return address === this || ((0, helpers_1.bytesCompare)(this._hash, address.hash) && this._workchain === address.workchain); } toString(type = 'base64', options) { const { workchain = this.workchain, bounceable = this.bounceable, testOnly = this.testOnly, urlSafe = true } = options || {}; if (typeof workchain !== 'number' || workchain < -128 || workchain >= 128) { throw new Error('Address: workchain must be int8.'); } if (typeof bounceable !== 'boolean') { throw new Error('Address: bounceable flag must be a boolean.'); } if (typeof testOnly !== 'boolean') { throw new Error('Address: testOnly flag must be a boolean.'); } if (typeof urlSafe !== 'boolean') { throw new Error('Address: urlSafe flag must be a boolean.'); } if (type === 'raw') { return `${workchain}:${(0, helpers_1.bytesToHex)(this._hash)}`.toUpperCase(); } const tag = Address.encodeTag({ bounceable, testOnly }); const address = new Uint8Array([tag, workchain, ...this._hash]); const checksum = (0, checksum_1.crc16BytesBe)(address); const base64 = (0, helpers_1.bytesToBase64)(new Uint8Array([...address, ...checksum])); return urlSafe ? base64.replace(/\//g, '_').replace(/\+/g, '-') : base64.replace(/_/g, '/').replace(/-/g, '+'); } static isAddress(address) { return address instanceof Address; } static isValid(address) { try { new Address(address); return true; } catch (e) { return false; } } } exports.Address = Address; Address.NONE = null; //# sourceMappingURL=address.js.map