UNPKG

@stellar/stellar-sdk

Version:

A library for working with the Stellar network, including communication with the Horizon and Soroban RPC servers.

272 lines (269 loc) 7.99 kB
import '../../node_modules/.pnpm/@stellar_js-xdr@4.0.0/node_modules/@stellar/js-xdr/src/int.js'; import { Hyper } from '../../node_modules/.pnpm/@stellar_js-xdr@4.0.0/node_modules/@stellar/js-xdr/src/hyper.js'; import '../../node_modules/.pnpm/@stellar_js-xdr@4.0.0/node_modules/@stellar/js-xdr/src/unsigned-int.js'; import { UnsignedHyper } from '../../node_modules/.pnpm/@stellar_js-xdr@4.0.0/node_modules/@stellar/js-xdr/src/unsigned-hyper.js'; import '../../node_modules/.pnpm/@stellar_js-xdr@4.0.0/node_modules/@stellar/js-xdr/src/xdr-type.js'; import 'buffer'; import { Uint128 } from './uint128.js'; import { Uint256 } from './uint256.js'; import { Int128 } from './int128.js'; import { Int256 } from './int256.js'; import types from '../generated/curr_generated.js'; class XdrLargeInt { int; type; /** * @param type - specifies a data type to use to represent the integer, one * of: 'i64', 'u64', 'i128', 'u128', 'i256', 'u256', 'timepoint', and 'duration' * (see {@link XdrLargeInt.isType}) * @param values - a list of integer-like values interpreted in big-endian order */ constructor(type, values) { if (!(values instanceof Array)) { values = [values]; } const normalizedValues = values.map((i) => { if (typeof i === "bigint") { return i; } if (typeof i === "object" && i !== null && "toBigInt" in i && typeof i.toBigInt === "function") { return i.toBigInt(); } return BigInt(i); }); switch (type) { case "i64": this.int = new Hyper(normalizedValues); break; case "i128": this.int = new Int128(...normalizedValues); break; case "i256": this.int = new Int256(...normalizedValues); break; case "u64": case "timepoint": case "duration": this.int = new UnsignedHyper(normalizedValues); break; case "u128": this.int = new Uint128(...normalizedValues); break; case "u256": this.int = new Uint256(...normalizedValues); break; default: throw TypeError(`invalid type: ${type}`); } this.type = type; } /** * Converts to a native JS number. * * @throws if the value can't fit into a Number */ toNumber() { const bi = this.int.toBigInt(); if (bi > Number.MAX_SAFE_INTEGER || bi < Number.MIN_SAFE_INTEGER) { throw RangeError( `value ${bi} not in range for Number [${Number.MAX_SAFE_INTEGER}, ${Number.MIN_SAFE_INTEGER}]` ); } return Number(bi); } /** Converts to a native BigInt. */ toBigInt() { return this.int.toBigInt(); } /** * The integer encoded with `ScValType = I64`. * * @throws if the value cannot fit in 64 bits */ toI64() { this._sizeCheck(64); const v = this.toBigInt(); if (BigInt.asIntN(64, v) !== v) { throw RangeError(`value too large for i64: ${v}`); } return types.ScVal.scvI64(new types.Int64(v)); } /** The integer encoded with `ScValType = U64` */ toU64() { this._sizeCheck(64); return types.ScVal.scvU64( new types.Uint64(BigInt.asUintN(64, this.toBigInt())) // reiterpret as unsigned ); } /** The integer encoded with `ScValType = Timepoint` */ toTimepoint() { this._sizeCheck(64); return types.ScVal.scvTimepoint( new types.Uint64(BigInt.asUintN(64, this.toBigInt())) // reiterpret as unsigned ); } /** The integer encoded with `ScValType = Duration` */ toDuration() { this._sizeCheck(64); return types.ScVal.scvDuration( new types.Uint64(BigInt.asUintN(64, this.toBigInt())) // reiterpret as unsigned ); } /** * The integer encoded with `ScValType = I128`. * * @throws if the value cannot fit in 128 bits */ toI128() { this._sizeCheck(128); const v = this.int.toBigInt(); if (BigInt.asIntN(128, v) !== v) { throw RangeError(`value too large for i128: ${v}`); } const hi64 = BigInt.asIntN(64, v >> 64n); const lo64 = BigInt.asUintN(64, v); return types.ScVal.scvI128( new types.Int128Parts({ hi: new types.Int64(hi64), lo: new types.Uint64(lo64) }) ); } /** * The integer encoded with `ScValType = U128`. * * @throws if the value cannot fit in 128 bits */ toU128() { this._sizeCheck(128); const v = this.int.toBigInt(); return types.ScVal.scvU128( new types.UInt128Parts({ hi: new types.Uint64(BigInt.asUintN(64, v >> 64n)), lo: new types.Uint64(BigInt.asUintN(64, v)) }) ); } /** * The integer encoded with `ScValType = I256` * * @throws if the value cannot fit in a signed 256-bit integer */ toI256() { const v = this.int.toBigInt(); if (BigInt.asIntN(256, v) !== v) { throw RangeError(`value too large for i256: ${v}`); } const hiHi64 = BigInt.asIntN(64, v >> 192n); const hiLo64 = BigInt.asUintN(64, v >> 128n); const loHi64 = BigInt.asUintN(64, v >> 64n); const loLo64 = BigInt.asUintN(64, v); return types.ScVal.scvI256( new types.Int256Parts({ hiHi: new types.Int64(hiHi64), hiLo: new types.Uint64(hiLo64), loHi: new types.Uint64(loHi64), loLo: new types.Uint64(loLo64) }) ); } /** * The integer encoded with `ScValType = U256` * * Note: No size check needed - U256 is the largest unsigned type. */ toU256() { const v = this.int.toBigInt(); const hiHi64 = BigInt.asUintN(64, v >> 192n); const hiLo64 = BigInt.asUintN(64, v >> 128n); const loHi64 = BigInt.asUintN(64, v >> 64n); const loLo64 = BigInt.asUintN(64, v); return types.ScVal.scvU256( new types.UInt256Parts({ hiHi: new types.Uint64(hiHi64), hiLo: new types.Uint64(hiLo64), loHi: new types.Uint64(loHi64), loLo: new types.Uint64(loLo64) }) ); } /** The smallest interpretation of the stored value */ toScVal() { switch (this.type) { case "i64": return this.toI64(); case "i128": return this.toI128(); case "i256": return this.toI256(); case "u64": return this.toU64(); case "u128": return this.toU128(); case "u256": return this.toU256(); case "timepoint": return this.toTimepoint(); case "duration": return this.toDuration(); default: throw TypeError(`invalid type: ${this.type}`); } } /** Returns the primitive value of this integer. */ valueOf() { return this.int.valueOf(); } /** Returns the string representation of this integer. */ toString() { return this.int.toString(); } /** Returns a JSON-friendly representation with `value` and `type` fields. */ toJSON() { return { value: this.toBigInt().toString(), type: this.type }; } _sizeCheck(bits) { if (this.int.size > bits) { throw RangeError(`value too large for ${bits} bits (${this.type})`); } } /** Returns true if the given string is a valid XDR large integer type name. */ static isType(type) { switch (type) { case "i64": case "i128": case "i256": case "u64": case "u128": case "u256": case "timepoint": case "duration": return true; default: return false; } } /** * Convert the raw `ScValType` string (e.g. 'scvI128', generated by the XDR) * to a type description for {@link XdrLargeInt} construction (e.g. 'i128') * * @param scvType - the `xdr.ScValType` as a string * @returns the corresponding {@link ScIntType} if it's an integer type, or * `undefined` if it's not an integer type */ static getType(scvType) { const type = scvType.slice(3).toLowerCase(); if (this.isType(type)) { return type; } return void 0; } } export { XdrLargeInt }; //# sourceMappingURL=xdr_large_int.js.map