UNPKG

@arkiv-network/sdk

Version:

TypeScript client library for Arkiv's blockchains interactions

1,312 lines • 52.1 kB
let viem = require("viem");

//#region src/schema/errors.ts
/**
* A value was rejected by its tagged constructor — out of range, wrong length, bad checksum, too
* much precision, and so on.
*
* The message names the offending value and, where there is one, the type that *would* hold it, so
* the fix is in the error rather than in the docs.
*/
var InvalidValueError = class extends Error {
	/** The type tag whose constructor rejected the value. */
	tag;
	/** The rejected input, as given. */
	input;
	constructor(tag, input, reason, hint) {
		super(`Invalid ${tag} value ${describe(input)}: ${reason}.${hint ? ` ${hint}` : ""}`);
		this.name = "InvalidValueError";
		this.tag = tag;
		this.input = input;
	}
};
/**
* A bare JavaScript value could not be given a type. Raised when an attribute or predicate is
* handed something that is neither a tagged value nor one of the five bare forms
* (`boolean`, `number`, `bigint`, `string`, `Uint8Array`).
*/
var UntypedValueError = class extends Error {
	input;
	constructor(input) {
		super(`Cannot infer an Arkiv type for ${describe(input)}. Attribute values must be a tagged value (i32, u64, u256, dec, str, addr, key, bytes, bool) or a bare boolean, number, bigint, string or Uint8Array.`);
		this.name = "UntypedValueError";
		this.input = input;
	}
};
/**
* An attribute was given `undefined` or `null` as its value.
*
* There is no such thing as an attribute with no value: an attribute either exists with a type, or
* is not set. The fix is always to leave the name out rather than to write an empty value — or, to
* remove a column from an existing entity, to `unset` it in a patch — so this is called out
* separately from {@link UntypedValueError}: the remedy is different.
*
* `createEntity` and `patchEntity` already treat a column given as `undefined` as left out, so
* through them only `null` raises this.
*/
var MissingValueError = class extends Error {
	/** The attribute whose value was missing, when raised from an attribute map. */
	attributeName;
	constructor(input, attributeName) {
		const subject = attributeName ? `attribute "${attributeName}"` : "attribute value";
		super(`The ${subject} is ${input === null ? "null" : "undefined"}. An attribute is either set with a value and a type or not set at all, so there is nothing to write here. ` + (attributeName ? `Leave "${attributeName}" out of the values (or a patch's "set") instead — e.g. build the object conditionally, or drop the key when the value is absent. To remove the column from an existing entity, list it in a patch's "unset".` : "Omit the attribute instead of giving it an empty value."));
		this.name = "MissingValueError";
		this.attributeName = attributeName;
	}
};
/** An attribute name violated the on-chain name grammar. */
var InvalidAttributeNameError = class extends Error {
	attributeName;
	constructor(attributeName, reason) {
		super(`Invalid attribute name "${attributeName}": ${reason}. Names must be 1-32 bytes, start with a letter, and contain only A-Z, a-z, 0-9, ".", "-" or "_". Names are case-sensitive.`);
		this.name = "InvalidAttributeNameError";
		this.attributeName = attributeName;
	}
};
/**
* One patch tried to both write and remove the same attribute.
*/
var ConflictingMutationError = class extends Error {
	attributeName;
	constructor(attributeName) {
		super(`The patch both sets and unsets "${attributeName}". A patch applies one mutation per attribute, so say which you mean: drop it from "unset" to write the value, or from "set" to remove the attribute.`);
		this.name = "ConflictingMutationError";
		this.attributeName = attributeName;
	}
};
/**
* More attributes were supplied than an entity operation can carry — raised by `defineSchema` for a
* schema with more columns than one create could write.
*/
var TooManyAttributesError = class extends Error {
	/**
	* @param tagged - Whether `count` includes a named schema's tag, which the message then calls out:
	* the tag is not among the declared columns, so the count would otherwise look off by one.
	*/
	constructor(count, max, tagged = false) {
		super(`An entity may carry at most ${max} attributes, got ${count}.` + (tagged ? ` A named schema's tag counts as one of them, so it may declare at most ${max - 1} columns.` : ""));
		this.name = "TooManyAttributesError";
	}
};
/** The `bytes` values of one create or patch add up to more than `MAX_ENTITY_BYTES`. */
var EntityTooLargeError = class extends Error {
	constructor(total, max) {
		super(`The bytes columns of one create or patch may hold at most ${max} bytes in total, got ${total}. Split the data across entities, or store it elsewhere and keep a reference`);
		this.name = "EntityTooLargeError";
	}
};
/** A schema, or one of its columns, was defined in a way the SDK or the protocol cannot honour. */
var SchemaDefinitionError = class extends Error {
	/** The column at fault, when there is one. */
	columnName;
	constructor(reason, columnName) {
		super(`Invalid schema${columnName === void 0 ? "" : ` column "${columnName}"`}: ${reason}.`);
		this.name = "SchemaDefinitionError";
		this.columnName = columnName;
	}
};
/**
* Data did not fit its schema: a write named a column the schema does not have, left out one it
* requires, or gave one a value of the wrong type — or an entity read back through a schema lacks a
* required column or holds one with a different type.
*/
var SchemaMismatchError = class extends Error {
	/** The column at fault. */
	columnName;
	constructor(columnName, reason) {
		super(`Column "${columnName}": ${reason}.`);
		this.name = "SchemaMismatchError";
		this.columnName = columnName;
	}
};
/** The node sent back an attribute this SDK cannot decode. */
var UnknownAttributeTypeError = class extends Error {
	/** The type as the node named it — a tag over JSON-RPC, a typeId on the wire. */
	type;
	constructor(type) {
		super(`Unknown attribute type ${describe(type)}. The node is using a type this SDK version does not know about — upgrade @arkiv-network/sdk.`);
		this.name = "UnknownAttributeTypeError";
		this.type = type;
	}
};
/** Renders an arbitrary input for an error message, without ever throwing. */
function describe(input) {
	switch (typeof input) {
		case "string": return JSON.stringify(input.length > 64 ? `${input.slice(0, 61)}...` : input);
		case "bigint": return `${input}n`;
		case "object": return input === null ? "null" : safeJson(input);
		case "undefined": return "undefined";
		default: return String(input);
	}
}
function safeJson(input) {
	try {
		return JSON.stringify(input) ?? String(input);
	} catch {
		return Object.prototype.toString.call(input);
	}
}

//#endregion
//#region src/schema/decimal.ts
/**
* Decimal places a `dec` value is scaled by. Fixed by the protocol, so any two decimals are
* directly comparable — and range-indexable — as plain integers.
*/
const DECIMAL_SCALE = 18;
/** 10 ** {@link DECIMAL_SCALE} — the scaling factor between a `dec` and its integer units. */
const DECIMAL_UNIT = 10n ** BigInt(DECIMAL_SCALE);
/** The widest scaled value an `int256` holds. */
const INT256_MAX = 2n ** 255n - 1n;
/** The narrowest scaled value an `int256` holds. */
const INT256_MIN = -(2n ** 255n);
/**
* A decimal literal: an optional sign, at least one integer digit, and an optional fraction of at
* most {@link DECIMAL_SCALE} digits. Exponents are not part of the grammar — `1e18` is a parse
* error rather than a silent reinterpretation.
*/
const DECIMAL_RE = /^([+-]?)(\d+)(?:\.(\d+))?$/;
/**
* Parses a decimal literal into its scaled integer units.
*
* Excess fractional precision is an **error, never a rounding**: the protocol stores exactly 18
* decimal places, and silently dropping the 19th digit would make a stored value differ from the
* one that was written.
*
* @param input - The decimal literal, e.g. `"3.5"` or `"-0.000001"`.
* @returns The value scaled by 10 ** 18.
* @throws {InvalidValueError} If the literal is malformed, too precise, or out of `int256` range.
*/
function decimalToUnits(input) {
	const match = DECIMAL_RE.exec(input);
	if (!match) throw new InvalidValueError("dec", input, "not a decimal literal", "Write it as sign, digits, and an optional \".\" with up to 18 fractional digits — e.g. dec(\"3.5\") or dec(\"-0.25\"). Exponents such as \"1e18\" are not accepted.");
	const [, sign, whole, fraction = ""] = match;
	if (fraction.length > DECIMAL_SCALE) throw new InvalidValueError("dec", input, `${fraction.length} fractional digits exceeds the ${DECIMAL_SCALE} the protocol stores`, "Round it yourself before storing — a dec is never rounded for you, so that what you write is exactly what is stored.");
	const digits = BigInt(whole + fraction.padEnd(DECIMAL_SCALE, "0"));
	const units = sign === "-" ? -digits : digits;
	if (units > INT256_MAX || units < INT256_MIN) throw new InvalidValueError("dec", input, "exceeds the int256 range a dec is stored in");
	return units;
}
/**
* Renders scaled integer units back as a canonical decimal string: no leading zeros, no trailing
* fractional zeros, no `-0`. Parsing the result yields the same units, so this is the inverse of
* {@link decimalToUnits} on every value it accepts.
*
* @param units - The value scaled by 10 ** 18.
* @returns The canonical decimal string, e.g. `"3.5"`.
* @throws {InvalidValueError} If the units are outside the `int256` range.
*/
function unitsToDecimal(units) {
	if (units > INT256_MAX || units < INT256_MIN) throw new InvalidValueError("dec", units, "exceeds the int256 range a dec is stored in");
	const negative = units < 0n;
	const magnitude = negative ? -units : units;
	const whole = magnitude / DECIMAL_UNIT;
	const trimmed = (magnitude % DECIMAL_UNIT).toString().padStart(DECIMAL_SCALE, "0").replace(/0+$/, "");
	const sign = negative ? "-" : "";
	return trimmed ? `${sign}${whole}.${trimmed}` : `${sign}${whole}`;
}

//#endregion
//#region src/schema/types.ts
/**
* The protocol's attribute type vocabulary, mapping each short **tag** (the name used by the
* client, the query language and this SDK) to its **typeId** (the byte carried on the wire and in
* the entity record).
*
* The typeIds are consensus-critical: they are written into entity records and mixed into index
* keys, so this table must never drift from the node's `AttributeType`.
*
* | tag     | typeId | ABI wire type        | when indexed              |
* | ------- | ------ | -------------------- | ------------------------- |
* | `bool`  | 1      | `bool`               | equality + range          |
* | `i32`   | 2      | `int32`              | equality + range          |
* | `u64`   | 3      | `uint64`             | equality + range          |
* | `u256`  | 4      | `uint256`            | equality + range          |
* | `dec`   | 5      | `int256` (18 dp)     | equality + range          |
* | —       | 6      | `bytes32`            | reserved                  |
* | `bytes` | 7      | `bytes` (<= 128 KiB) | never indexed             |
* | `str`   | 8      | `string` (<= 128 B)  | equality + range + prefix |
* | `addr`  | 9      | `address`            | equality + range          |
* | `key`   | 10     | `bytes32`            | equality + range          |
*
* typeId 6 is the node's `bytes32` type, which this SDK does not expose: it is reserved here, so
* `TYPE_IDS` leaves it out, and a value of that type is read as a `key`.
*
* On the wire the typeId shares its byte with the indexed flag — see {@link INDEXED_FLAG}.
*/
const TYPE_IDS = {
	bool: 1,
	i32: 2,
	u64: 3,
	u256: 4,
	dec: 5,
	bytes: 7,
	str: 8,
	addr: 9,
	key: 10
};
/**
* Bit 7 of the `typeId` byte: set when the node should index the attribute. The low seven bits are
* the type itself, so `str` travels as `8` unindexed and `0x88` indexed.
*/
const INDEXED_FLAG = 128;
/** Whether attributes of this type may be indexed — everything except `bytes`. */
function isIndexable(tag) {
	return tag !== "bytes";
}
/**
* Builds a validated value. Module-internal: the constructors in `values.ts` call this **after**
* validating, which is what makes the {@link validated} brand meaningful.
*/
function makeValue(type, value) {
	return {
		type,
		value
	};
}
/**
* Whether `input` has the *shape* of an {@link ArkivValue} — a known type tag and a value.
*/
function isArkivValue(input) {
	return typeof input === "object" && input !== null && "type" in input && "value" in input && typeof input.type === "string" && Object.hasOwn(TYPE_IDS, input.type);
}

//#endregion
//#region src/schema/column.ts
/**
* Marks a column. A registry symbol rather than `instanceof`, so a column made by one copy of the
* SDK — its ESM build, say — is still recognised by another, such as the CJS build a dependency
* loaded.
*/
const COLUMN_BRAND = Symbol.for("@arkiv-network/sdk/column");
var ColumnDefinition = class ColumnDefinition {
	type;
	isIndexed;
	isOptional;
	defaultValue;
	#coerce;
	constructor(type, isIndexed, isOptional, defaultValue, coerce) {
		this.type = type;
		this.isIndexed = isIndexed;
		this.isOptional = isOptional;
		this.defaultValue = defaultValue;
		this.#coerce = coerce;
		Object.defineProperty(this, COLUMN_BRAND, { value: true });
		Object.freeze(this);
	}
	indexed() {
		if (this.type === "bytes") throw new SchemaDefinitionError("a bytes column cannot be indexed. Bytes are stored, never indexed, so they can be selected but not filtered on — index a hash of them, as a hex str, instead");
		return this.#with({ isIndexed: true });
	}
	optional() {
		return this.#with({ isOptional: true });
	}
	default(...args) {
		if (args.length === 0) throw new SchemaDefinitionError(`.default() needs a value — e.g. ${this.type}().default(...). Leave .default() off for a column the create must always provide`);
		return this.#with({ defaultValue: this.#coerce(this.type, args[0]) });
	}
	#with(changes) {
		return new ColumnDefinition(this.type, changes.isIndexed ?? this.isIndexed, changes.isOptional ?? this.isOptional, changes.defaultValue ?? this.defaultValue, this.#coerce);
	}
};
/**
* A fresh column of type `tag`: unindexed, required, no default. Internal seam for the type
* constructors, which return one when called with no arguments.
*/
function createColumn(tag, coerce) {
	return new ColumnDefinition(tag, false, false, void 0, coerce);
}
/** Whether `input` is a column, as opposed to a value or anything else. */
function isColumn(input) {
	return typeof input === "object" && input !== null && COLUMN_BRAND in input;
}

//#endregion
//#region src/schema/values.ts
/** The widest `i32`. */
const I32_MAX = 2147483647;
/** The narrowest `i32`. */
const I32_MIN = -2147483648;
/** The widest `u64`. */
const U64_MAX = 2n ** 64n - 1n;
/** The widest `u256`. */
const U256_MAX = 2n ** 256n - 1n;
/**
* The longest `str`, in UTF-8 bytes
*/
const MAX_STRING_BYTES = 128;
/**
* The longest `bytes` value, in bytes. The cap applies to each `bytes` attribute separately, but
* all the `bytes` values of one create or patch also share the `MAX_ENTITY_BYTES` budget.
*/
const MAX_BYTES_LENGTH = 128 * 1024;
/**
* Finds the first lone UTF-16 surrogate — a string the node would reject, since it has no UTF-8
* encoding. `TextEncoder` would quietly replace it with U+FFFD instead.
*/
function findLoneSurrogate(value) {
	for (let index = 0; index < value.length; index++) {
		const code = value.charCodeAt(index);
		if (code < 55296 || code > 57343) continue;
		const next = value.charCodeAt(index + 1);
		if (code <= 56319 && next >= 56320 && next <= 57343) {
			index++;
			continue;
		}
		return index;
	}
}
function bool(...args) {
	if (args.length === 0) return createColumn("bool", toTypedValue);
	const [value] = args;
	if (typeof value !== "boolean") throw new InvalidValueError("bool", value, "not a boolean");
	return makeValue("bool", value);
}
function i32(...args) {
	if (args.length === 0) return createColumn("i32", toTypedValue);
	const [value] = args;
	if (typeof value === "bigint") {
		if (value > BigInt(I32_MAX) || value < BigInt(I32_MIN)) throw new InvalidValueError("i32", value, outOfI32Range(value >= 0n));
		return makeValue("i32", Number(value));
	}
	if (typeof value !== "number" || !Number.isFinite(value)) throw new InvalidValueError("i32", value, "not a number");
	if (!Number.isInteger(value)) throw new InvalidValueError("i32", value, "not an integer", `Use dec(${JSON.stringify(String(value))}) for a fixed-point decimal.`);
	if (value > I32_MAX || value < I32_MIN) throw new InvalidValueError("i32", value, outOfI32Range(value >= 0));
	return makeValue("i32", value);
}
function outOfI32Range(nonNegative) {
	const range = `outside the i32 range [${I32_MIN}, ${I32_MAX}]`;
	return nonNegative ? `${range} — use u64(...) for large counters, timestamps and block heights (Date.now() does not fit an i32), or u256(...) beyond 2**64 - 1` : `${range} — use dec(...) for values that need more range than an i32`;
}
function u256(...args) {
	if (args.length === 0) return createColumn("u256", toTypedValue);
	return makeValue("u256", toUnsigned("u256", args[0], U256_MAX));
}
function u64(...args) {
	if (args.length === 0) return createColumn("u64", toTypedValue);
	return makeValue("u64", toUnsigned("u64", args[0], U64_MAX));
}
/**
* Parses and range-checks an unsigned integer for `tag`, whose widest value is `max`.
*
* Shared by {@link u64} and {@link u256} so the two differ in exactly one thing — their width —
* rather than in how they read a string or how they explain a failure.
*/
function toUnsigned(tag, value, max) {
	const parsed = toUnsignedBigint(tag, value);
	if (parsed < 0n) throw new InvalidValueError(tag, value, `negative — ${tag} is unsigned`, "Use i32(...) for small signed integers, or dec(...) for a signed fixed-point value.");
	if (parsed > max) throw new InvalidValueError(tag, value, `wider than ${tag === "u64" ? 64 : 256} bits`, tag === "u64" ? "Use u256(...) for values beyond 2**64 - 1." : void 0);
	return parsed;
}
function toUnsignedBigint(tag, value) {
	if (typeof value === "bigint") return value;
	if (typeof value === "number") {
		if (!Number.isInteger(value)) throw new InvalidValueError(tag, value, "not an integer", `Use dec(${JSON.stringify(String(value))}) for a fixed-point decimal.`);
		if (!Number.isSafeInteger(value)) throw new InvalidValueError(tag, value, "beyond the safe integer range, so it may already have lost precision", "Pass it as a bigint literal (e.g. 12345678901234567890n) or a string instead.");
		return BigInt(value);
	}
	if (typeof value === "string") {
		if (!/^(0x[0-9a-fA-F]+|\d+)$/.test(value)) throw new InvalidValueError(tag, value, "not a decimal or 0x-hex integer");
		return BigInt(value);
	}
	throw new InvalidValueError(tag, value, "not a bigint, number or string");
}
function dec(...args) {
	if (args.length === 0) return createColumn("dec", toTypedValue);
	const [value] = args;
	if (typeof value === "string") return makeValue("dec", unitsToDecimal(decimalToUnits(value)));
	if (typeof value === "bigint") return decFromUnits(value * DECIMAL_UNIT);
	if (typeof value !== "number" || !Number.isFinite(value)) throw new InvalidValueError("dec", value, "not a number");
	if (!Number.isInteger(value)) throw new InvalidValueError("dec", value, "a fractional number cannot be represented exactly in binary floating point", `Pass it as a string instead: dec(${JSON.stringify(String(value))}).`);
	return decFromUnits(BigInt(value) * DECIMAL_UNIT);
}
/**
* The exact scaled integer behind a `dec` — the value multiplied by 10 ** 18, which is what the
* protocol stores and compares. Use it when you need exact arithmetic; JavaScript has no native
* decimal type, so the SDK carries the canonical string and leaves the maths to you.
*
* @example
* decUnits(dec("3.5"))  // 3500000000000000000n
*/
function decUnits(value) {
	return decimalToUnits(value.value);
}
/**
* A `dec` built from its scaled integer units — the inverse of {@link decUnits}.
*
* @example
* decFromUnits(3_500_000_000_000_000_000n)  // dec("3.5")
*/
function decFromUnits(units) {
	return makeValue("dec", unitsToDecimal(units));
}
function str(...args) {
	if (args.length === 0) return createColumn("str", toTypedValue);
	const [value] = args;
	if (typeof value !== "string") throw new InvalidValueError("str", value, "not a string");
	const surrogate = findLoneSurrogate(value);
	if (surrogate !== void 0) throw new InvalidValueError("str", value, `contains a lone surrogate at index ${surrogate}, so it is not valid UTF-8`);
	const bytes$1 = (0, viem.stringToBytes)(value).length;
	if (bytes$1 > MAX_STRING_BYTES) throw new InvalidValueError("str", value, `${bytes$1} UTF-8 bytes exceeds the ${MAX_STRING_BYTES}-byte limit on a str`, "Store the long form in a bytes column and keep a short, queryable key here.");
	return makeValue("str", value);
}
function addr(...args) {
	if (args.length === 0) return createColumn("addr", toTypedValue);
	const [value] = args;
	if (typeof value !== "string" || !/^0x[0-9a-fA-F]{40}$/.test(value)) throw new InvalidValueError("addr", value, "not a 20-byte 0x-prefixed hex address");
	const body = value.slice(2);
	if (body !== body.toLowerCase() && body !== body.toUpperCase() && !(0, viem.isAddress)(value, { strict: true })) throw new InvalidValueError("addr", value, "fails its EIP-55 checksum, so a digit is probably mistyped", `If those hex digits are right, the correctly checksummed form is ${(0, viem.checksumAddress)(value)}.`);
	return makeValue("addr", (0, viem.checksumAddress)(value));
}
function key(...args) {
	if (args.length === 0) return createColumn("key", toTypedValue);
	return makeValue("key", asFixedHex("key", args[0], 32));
}
function bytes(...args) {
	if (args.length === 0) return createColumn("bytes", toTypedValue);
	const [value] = args;
	const hex = asHex("bytes", value);
	const length = (hex.length - 2) / 2;
	if (length > MAX_BYTES_LENGTH) throw new InvalidValueError("bytes", `<${length} bytes>`, `${length} bytes exceeds the ${MAX_BYTES_LENGTH}-byte limit on a bytes value`, "Split it across several entities, or store the bulk elsewhere and keep a reference.");
	return makeValue("bytes", hex);
}
/** Normalizes hex-or-bytes input of a known width into lowercase `0x` hex. */
function asFixedHex(tag, value, size$1) {
	if (value instanceof Uint8Array) {
		if (value.length !== size$1) throw new InvalidValueError(tag, `<${value.length} bytes>`, `not exactly ${size$1} bytes`);
		return (0, viem.toHex)(value);
	}
	const hex = asHex(tag, value);
	if (hex.length !== 2 + size$1 * 2) throw new InvalidValueError(tag, value, `${(hex.length - 2) / 2} bytes, not exactly ${size$1} bytes`);
	return hex;
}
/** Normalizes hex-or-bytes input into lowercase `0x` hex of a whole number of bytes. */
function asHex(tag, value) {
	if (value instanceof Uint8Array) return (0, viem.toHex)(value);
	if (typeof value !== "string" || !(0, viem.isHex)(value, { strict: true })) throw new InvalidValueError(tag, value, "not 0x-prefixed hex");
	if (value.length % 2 !== 0) throw new InvalidValueError(tag, value, "an odd number of hex digits, so not whole bytes");
	return value.toLowerCase();
}
/**
* Resolves a {@link ValueInput} to a typed value, applying the bare-form defaults above. Tagged
* values pass through untouched.
*
* @param input - The value to resolve.
* @param attributeName - The attribute this value belongs to, used to make errors name it.
*
* @throws {MissingValueError} If the input is `undefined` or `null` — an attribute is either set
* with a value and a type, or not set at all.
* @throws {UntypedValueError} If the input is not a tagged value or a bare boolean, number, bigint,
* string or `Uint8Array`.
* @throws {InvalidValueError} If a bare value does not fit the type it defaults to.
*
* @example
* toValue(10)          // i32(10)
* toValue(10n)         // u256(10n)
* toValue("hello")     // str("hello")
* toValue(dec("3.5"))  // unchanged
*/
function toValue(input, attributeName) {
	if (input === void 0 || input === null) throw new MissingValueError(input, attributeName);
	switch (typeof input) {
		case "boolean": return bool(input);
		case "number": return i32(input);
		case "bigint": return u256(input);
		case "string": return str(input);
		default: {
			if (input instanceof Uint8Array) return bytes(input);
			if (isArkivValue(input)) return revalidate(input);
			const candidate = input;
			if (isColumn(candidate)) throw columnGivenAsValue(candidate);
			throw new UntypedValueError(input);
		}
	}
}
/**
* Resolves `input` to a value of type `tag` — a tagged value of that type, or whatever `tag`'s
* constructor accepts. What a column's `.default(...)` runs its argument through.
*
* @throws {InvalidValueError} If the input does not make a valid value of type `tag`.
*/
function toTypedValue(tag, input) {
	if (isArkivValue(input)) {
		const value = revalidate(input);
		if (value.type !== tag) throw new InvalidValueError(tag, input, `a ${value.type} value, not a ${tag}`);
		return value;
	}
	if (isColumn(input)) throw columnGivenAsValue(input);
	const construct = CONSTRUCTORS[tag];
	return construct(input);
}
function columnGivenAsValue(column) {
	return new InvalidValueError(column.type, `<${column.type} column>`, "a column, not a value", `Pass the value itself, e.g. ${column.type}(...) with an argument — ${column.type}() with none declares a schema column.`);
}
/** Each tag's constructor, called with a value. */
const CONSTRUCTORS = {
	bool,
	i32,
	u64,
	u256,
	dec,
	bytes,
	str,
	addr,
	key
};
/**
* Re-runs a tagged value through its own constructor.
*
* {@link isArkivValue} can only check shape — the `validated` brand is a type-level construct with
* no runtime existence, so a hand-written `{ type: "u256", value: "1000" }` (from `JSON.parse`, a
* config file, an `as any` boundary) is indistinguishable from a real `u256(1000n)`. Passing it
* through unchecked was silent corruption rather than an error: the ABI encoder would take the
* *string* "1000" and write its UTF-8 bytes into the word, storing 2.27e76 on chain.
*
* Running the constructor again is what makes the brand's promise — "every value crossing the wire
* has been range-, length- and format-checked" — true at runtime. For a value that really did come
* from a constructor it is a no-op that returns an equal value.
*/
function revalidate(value) {
	switch (value.type) {
		case "bool": return bool(value.value);
		case "i32": return i32(value.value);
		case "u64": return u64(value.value);
		case "u256": return u256(value.value);
		case "dec": return dec(value.value);
		case "bytes": return bytes(value.value);
		case "str": return str(value.value);
		case "addr": return addr(value.value);
		case "key": return key(value.value);
	}
}

//#endregion
//#region src/schema/codec.ts
function strFromChain(value) {
	return makeValue("str", value);
}
/**
* The `typeId` marking a tombstone — an attribute being unset. It carries a zero-length value and
* is legal only in a patch's mutation list, never in a create.
*/
const TOMBSTONE_TYPE_ID = 0;
/**
* The node's `bytes32` type, which this SDK does not expose. Its values are 32 bytes, as a `key`'s
* are, so they are read as `key`s.
*/
const BYTES32_TYPE_ID = 6;
const BYTES32_TAG = "bytes32";
/**
* Encodes a typed value into the `bytes` the ABI carries for it.
*
* This and {@link decodeValueBytes} are the only place the value/wire mapping is written down.
*
* - Word types (`bool`, `i32`, `u64`, `u256`, `dec`, `addr`, `key`) become exactly 32
*   bytes, in the encoding Solidity would use — right-aligned, and sign-extended for `i32`.
* - `str` becomes its raw UTF-8 bytes, and `bytes` its raw bytes: variable length, no padding.
*/
function encodeValueBytes(value) {
	switch (value.type) {
		case "bool": return (0, viem.pad)(value.value ? "0x01" : "0x00", { size: 32 });
		case "i32": return (0, viem.toHex)(BigInt.asUintN(256, BigInt(value.value)), { size: 32 });
		case "u64":
		case "u256": return (0, viem.toHex)(value.value, { size: 32 });
		case "dec": return (0, viem.toHex)(BigInt.asUintN(256, decUnits(value)), { size: 32 });
		case "key": return value.value;
		case "addr": return (0, viem.pad)(value.value.toLowerCase(), { size: 32 });
		case "str": return (0, viem.toHex)((0, viem.stringToBytes)(value.value));
		case "bytes": return value.value;
	}
}
/**
* Encodes a named, typed attribute into its ABI form.
*
* @param name - The attribute name. Assumed already validated.
* @param indexed - Whether the node should index it. Never true for `bytes`, which the engine
* rejects with the flag set.
* @throws {InvalidValueError} If asked to index a `bytes` value.
*/
function encodeAbiAttribute(name, value, indexed) {
	if (indexed && value.type === "bytes") throw new InvalidValueError("bytes", `<${name}>`, "bytes are stored, never indexed");
	return {
		name: (0, viem.toHex)(name, { size: 32 }),
		typeId: TYPE_IDS[value.type] | (indexed ? INDEXED_FLAG : 0),
		value: encodeValueBytes(value)
	};
}
/**
* Splits a wire `typeId` into its type and indexed flag.
*
* The node's `bytes32` (typeId 6) decodes as `key`.
*
* @throws {UnknownAttributeTypeError} If the low seven bits name no known type.
*/
function decodeTypeId(typeId) {
	const base = typeId & ~INDEXED_FLAG;
	const tag = base === BYTES32_TYPE_ID ? "key" : Object.keys(TYPE_IDS).find((candidate) => TYPE_IDS[candidate] === base);
	if (tag === void 0) throw new UnknownAttributeTypeError(typeId);
	return {
		tag,
		indexed: (typeId & INDEXED_FLAG) !== 0
	};
}
/** Encodes a tombstone — the mutation that unsets `name`. Legal only in a patch. */
function encodeTombstone(name) {
	return {
		name: (0, viem.toHex)(name, { size: 32 }),
		typeId: TOMBSTONE_TYPE_ID,
		value: "0x"
	};
}
/**
* Decodes an attribute value as it comes back over JSON-RPC.
*
* The JSON encoding follows the value's **declared type**, never its magnitude: `bool` is a JSON
* boolean, `i32` a JSON number, `u64`/`u256` a `0x` QUANTITY, `dec` a decimal string, `str` a
* string, and
* the byte-shaped types `0x` DATA. Decimal strings are also accepted for the integer types, so this
* keeps working against a node that renders them that way.
*
* @param type - The type tag the response declared, e.g. `"u256"`.
* @param value - The JSON value.
* @throws {UnknownAttributeTypeError} If the tag names no known type.
* @throws {InvalidValueError} If the value does not parse as that type.
*/
function decodeRpcValue(type, value) {
	switch (asTypeTag(type)) {
		case "bool": return bool(asBoolean(value));
		case "i32": return i32(Number(asIntegerish("i32", value)));
		case "u64": return u64(asIntegerish("u64", value));
		case "u256": return u256(asIntegerish("u256", value));
		case "dec": return dec(asString("dec", value));
		case "key": return key(asString("key", value));
		case "addr": return addr(asString("addr", value));
		case "str": return strFromChain(asString("str", value));
		case "bytes": return makeValue("bytes", asString("bytes", value).toLowerCase());
	}
}
/**
* Narrows a type tag as the node spelled it. The node's `bytes32` narrows to `key`.
*
* @throws {UnknownAttributeTypeError} If it names no type this SDK knows.
*/
function asTypeTag(type) {
	if (typeof type !== "string" || !Object.hasOwn(TYPE_IDS, type)) {
		if (type === BYTES32_TAG) return "key";
		throw new UnknownAttributeTypeError(type);
	}
	return type;
}
function asBoolean(value) {
	if (typeof value === "boolean") return value;
	if (value === "true" || value === "false") return value === "true";
	throw new InvalidValueError("bool", value, "not a boolean");
}
function asString(tag, value) {
	if (typeof value !== "string") throw new InvalidValueError(tag, value, `expected a string, got ${typeof value}`);
	return value;
}
/** A `0x` QUANTITY, a JSON number, or a decimal string — all of which name one integer. */
function asIntegerish(tag, value) {
	if (typeof value === "number") {
		if (!Number.isInteger(value)) throw new InvalidValueError(tag, value, "not an integer");
		return BigInt(value);
	}
	if (typeof value === "bigint") return value;
	if (typeof value === "string") {
		if (/^0x[0-9a-fA-F]+$/.test(value)) return BigInt(value);
		if (/^-?\d+$/.test(value)) return BigInt(value);
	}
	throw new InvalidValueError(tag, value, "not an integer");
}

//#endregion
//#region src/schema/names.ts
/** The longest attribute name, in bytes — the width of the on-chain `Ident32` name cell. */
const MAX_NAME_BYTES = 32;
/**
* The attribute-name grammar (`Ident32`): a leading letter, then letters, digits, `.`, `-` or `_`.
*
* Names are **case-sensitive** — `Level` and `level` are two different attributes.
*
* The charset is ASCII-only, so a name's length in characters is also its length in bytes.
*/
const NAME_RE = /^[A-Za-z][A-Za-z0-9._-]*$/;
/**
* Words the query language reserves. They are rejected as attribute names because an attribute
* named `not` or `str` could be written but never queried — the parser would read the name as an
* operator or a type tag.
*
* Matched **case-insensitively**: query keywords are case-insensitive, so `NOT` and `not` are the
* same operator, and the type tags are held to the same rule so that what is reserved does not
* depend on how you happen to capitalise it.
*/
const RESERVED = new Set([
	"and",
	"or",
	"not",
	"true",
	"false",
	"between",
	"startswith",
	"exists",
	"typeof",
	"order",
	"by",
	"asc",
	"desc",
	"bool",
	"i32",
	"u64",
	"u256",
	"dec",
	"bytes",
	"str",
	"addr",
	"key"
]);
/**
* Validates an attribute name against the engine's `Ident32` grammar and the query language's
* reserved words.
*
* @param name - The attribute name.
* @throws {InvalidAttributeNameError} If the name is empty, starts with `$` (reserved for system
* attributes), too long, uses characters outside the grammar, contains `--` (which opens a query
* comment), or collides with a reserved word.
*/
function validateAttributeName(name) {
	if (typeof name !== "string" || name.length === 0) throw new InvalidAttributeNameError(String(name), "the name is empty");
	if (name.startsWith("$")) throw new InvalidAttributeNameError(name, "\"$\" is reserved for system attributes, which the engine sets and you cannot write");
	if (!NAME_RE.test(name)) {
		const chars = [...name];
		const at = chars.findIndex((char, index) => !(index === 0 ? /[A-Za-z]/ : /[A-Za-z0-9._-]/).test(char));
		throw new InvalidAttributeNameError(name, at === 0 ? `it starts with "${chars[0]}" rather than a letter` : `it contains "${chars[at]}" at position ${at}`);
	}
	if (name.length > MAX_NAME_BYTES) throw new InvalidAttributeNameError(name, `the name is ${name.length} bytes long`);
	if (name.includes("--")) throw new InvalidAttributeNameError(name, "\"--\" opens a comment in the query language, so everything after it in a query would be discarded — an attribute with this name could be written but never safely queried");
	if (RESERVED.has(name.toLowerCase())) throw new InvalidAttributeNameError(name, `"${name}" is reserved by the query language, so an attribute with this name could never be queried`);
}
/** Whether `name` is a valid attribute name — the non-throwing form of {@link validateAttributeName}. */
function isValidAttributeName(name) {
	try {
		validateAttributeName(name);
		return true;
	} catch {
		return false;
	}
}

//#endregion
//#region src/schema/schema.ts
/**
* The most attributes one entity operation may carry, and so the most columns a schema may have —
* one fewer for a named schema, whose tag is one more attribute on every create.
*/
const MAX_ATTRIBUTES = 32;
/**
* The attribute a named schema tags its entities with: an indexed `str` holding the schema's name.
* Creates write it, and `.from(schema)` filters on it, so a query through a schema only ever sees
* entities written through it.
*/
const SCHEMA_ATTRIBUTE = "arkiv.schema";
/**
* Marks a schema. A registry symbol rather than `instanceof`, so a schema defined through one copy
* of the SDK — its CJS build, say — is still recognised by another, such as the ESM build an app
* loaded.
*/
const SCHEMA_BRAND = Symbol.for("@arkiv-network/sdk/schema");
/**
* A schema: the named, typed attributes an entity of one kind carries, and which of them the node
* indexes. Built with {@link defineSchema}.
*
* A schema is an SDK-side convention. The node sees only attributes, each with a type and an
* indexed flag; the schema is what types the SDK's writes and reads, and checks them at runtime.
*
* A named schema also tags every entity it creates with its name, in the indexed
* {@link SCHEMA_ATTRIBUTE} attribute, so that a query through it sees only its own entities.
*
* @typeParam C - The columns, keyed by attribute name.
*/
var Schema = class {
	/** The name entities are tagged with, or `undefined` for an untagged schema. */
	name;
	/** The columns, keyed by attribute name, in the order they were declared. */
	columns;
	/** The tag every create writes and every query filters on, if the schema is named. */
	tag;
	/** Use {@link defineSchema}. */
	constructor(name, columns) {
		this.tag = name === void 0 ? void 0 : validateName(name);
		validateColumns(columns, name !== void 0);
		this.name = name;
		this.columns = Object.freeze({ ...columns });
		Object.defineProperty(this, SCHEMA_BRAND, { value: true });
		Object.freeze(this);
	}
};
function defineSchema(...args) {
	return args.length === 2 ? new Schema(args[0], args[1]) : new Schema(void 0, args[0]);
}
function validateName(name) {
	if (typeof name !== "string" || name.length === 0) throw new SchemaDefinitionError("a schema name must be a non-empty string — leave it out for an untagged schema");
	try {
		return str(name);
	} catch (error) {
		if (!(error instanceof InvalidValueError)) throw error;
		throw new SchemaDefinitionError(`the name is not a valid str tag. ${error.message}`);
	}
}
function validateColumns(columns, tagged) {
	if (typeof columns !== "object" || columns === null || Array.isArray(columns)) throw new SchemaDefinitionError("defineSchema takes an object of columns keyed by name");
	const entries = Object.entries(columns);
	const attributes = entries.length + (tagged ? 1 : 0);
	if (attributes > MAX_ATTRIBUTES) throw new TooManyAttributesError(attributes, MAX_ATTRIBUTES, tagged);
	for (const [name, column] of entries) {
		validateAttributeName(name);
		if (name === SCHEMA_ATTRIBUTE) throw new SchemaDefinitionError(`"${name}" is the attribute a named schema tags its entities with, so a column cannot use it. Pick another name`, name);
		if (!isColumn(column)) throw notAColumn(name, column);
	}
}
/** Whether `input` is a schema built with {@link defineSchema}. */
function isSchema(input) {
	return typeof input === "object" && input !== null && SCHEMA_BRAND in input;
}
/**
* The column `name` of `schema`, or `undefined` if it has none. Only the schema's own columns
* count, so an inherited key such as `toString` or `__proto__` is not mistaken for one.
*/
function lookupColumn(schema, name) {
	return Object.hasOwn(schema.columns, name) ? schema.columns[name] : void 0;
}
/** The schema's column names, for an error message that has to say what would have worked. */
function describeColumns(schema) {
	return Object.keys(schema.columns).join(", ") || "(none)";
}
function notAColumn(name, input) {
	if (isArkivValue(input)) return new SchemaDefinitionError(`got a ${input.type} value where a column belongs. Did you mean ${input.type}().default(${defaultArgument(input)})? Called with a value, ${input.type}(...) makes a value; called with none, ${input.type}() declares a column`, name);
	return new SchemaDefinitionError("not a column. Declare it with a type constructor called with no arguments, e.g. str() or dec().indexed()", name);
}
/** A value spelled as the argument its constructor would take, for an error message. */
function defaultArgument(value) {
	switch (value.type) {
		case "bool":
		case "i32": return String(value.value);
		case "u64":
		case "u256": return `${value.value}n`;
		default: return JSON.stringify(value.value);
	}
}

//#endregion
//#region src/schema/attributes.ts
/**
* The most data the `bytes` columns of one create or patch may hold together, in bytes. Each
* `bytes` value is also capped on its own, at `MAX_BYTES_LENGTH`.
*
* Provisional: the protocol has not settled a per-entity cap yet, so this keeps the budget the
* single payload had — and an operation much larger than it would not fit in a transaction the
* node accepts anyway.
*/
const MAX_ENTITY_BYTES = 128 * 1024;
/**
* Encodes a create's values into the ABI attribute array it carries: every column the
* values name, plus the default of every defaulted column they leave out, each flagged indexed or
* not as its column says — and, for a named schema, the indexed tag that marks the entity as its.
*
* @throws {SchemaDefinitionError} If `schema` is not a schema built with `defineSchema`.
* @throws {TypeError} If `values` is not an object.
* @throws {SchemaMismatchError} If a value names a column the schema lacks, a required column is
* left out, or a value's type is not its column's.
* @throws {MissingValueError} If a value is `null`.
* @throws {UntypedValueError} If a value is neither a tagged value nor a bare form.
* @throws {InvalidValueError} If a value does not fit its type.
* @throws {EntityTooLargeError} If the `bytes` values add up to more than {@link MAX_ENTITY_BYTES}.
*/
function encodeCreate(schema, values) {
	assertSchema(schema);
	for (const name of keysOf(values, "create")) columnFor(schema, name, "create");
	const attributes = [];
	if (schema.tag !== void 0) attributes.push(encodeAbiAttribute(SCHEMA_ATTRIBUTE, schema.tag, true));
	for (const [name, column] of Object.entries(schema.columns)) {
		const input = Object.hasOwn(values, name) ? values[name] : void 0;
		if (input === void 0) {
			if (column.defaultValue !== void 0) attributes.push(encodeAbiAttribute(name, column.defaultValue, column.isIndexed));
			else if (!column.isOptional) throw new SchemaMismatchError(name, `the create leaves out a required ${column.type} column. Give it a value, or declare it ${column.type}().optional() or with a .default(...)`);
			continue;
		}
		attributes.push(encodeColumn(name, column, input));
	}
	assertBytesFit(attributes);
	return attributes.sort(byName);
}
/**
* Encodes a patch into the ABI attribute array it carries: a write for each column in `set`, with
* the indexed flag its column declares, and a tombstone for each name in `unset`. A column `set`
* to `undefined` is left out, as it is from a create.
*
* Writing a column with a different indexed flag than the entity holds flips its indexing, so a
* schema that marks a column `.indexed()` indexes it from the next patch that writes it.
*
* @throws {SchemaDefinitionError} If `schema` is not a schema built with `defineSchema`.
* @throws {SchemaMismatchError} If a name is not a column, a value's type is not its column's, or
* `unset` names a required column.
* @throws {ConflictingMutationError} If a name appears in both `set` and `unset`.
* @throws {MissingValueError} If a value in `set` is `null`.
* @throws {UntypedValueError} If a value in `set` is neither a tagged value nor a bare form.
* @throws {InvalidValueError} If a value does not fit its type.
* @throws {EntityTooLargeError} If the `bytes` values in `set` add up to more than
* {@link MAX_ENTITY_BYTES}.
* @throws {TypeError} If `set` is not an object, or `unset` is not an array.
*/
function encodePatch(schema, { set = {}, unset = [] }) {
	assertSchema(schema);
	const mutations = [];
	for (const name of keysOf(set, "patch")) {
		const column = columnFor(schema, name, "patch");
		const input = set[name];
		if (input !== void 0) mutations.push(encodeColumn(name, column, input));
	}
	if (!Array.isArray(unset)) throw new TypeError(`"unset" must be an array of column names`);
	for (const name of new Set(unset)) {
		const column = columnFor(schema, name, "patch");
		if (!column.isOptional) throw new SchemaMismatchError(name, `a required column, so unsetting it would leave the entity without a value its schema requires. Declare it ${column.type}().optional() to allow that`);
		if (Object.hasOwn(set, name) && set[name] !== void 0) throw new ConflictingMutationError(name);
		mutations.push(encodeTombstone(name));
	}
	assertBytesFit(mutations);
	return mutations.sort(byName);
}
function assertSchema(schema) {
	if (!isSchema(schema)) throw new SchemaDefinitionError("expected a schema built with defineSchema(...) — writes are typed by the schema they name");
}
function keysOf(values, operation) {
	if (typeof values !== "object" || values === null) throw new TypeError(`The ${operation} values must be an object keyed by column name`);
	return Object.keys(values);
}
function columnFor(schema, name, operation) {
	const column = lookupColumn(schema, name);
	if (column === void 0) throw new SchemaMismatchError(name, `the ${operation} names a column this schema does not have. Its columns are ` + describeColumns(schema));
	return column;
}
/** One column's value, resolved, checked against the column's type, and encoded. */
function encodeColumn(name, column, input) {
	const value = toValue(input, name);
	if (value.type !== column.type) throw new SchemaMismatchError(name, `a ${column.type} column, but the value is a ${value.type}. Write ${column.type}(...) around the value`);
	return encodeAbiAttribute(name, value, column.isIndexed);
}
/** Throws if the `bytes` values among `attributes` add up to more than {@link MAX_ENTITY_BYTES}. */
function assertBytesFit(attributes) {
	let total = 0;
	for (const { typeId, value } of attributes) if ((typeId & ~INDEXED_FLAG) === TYPE_IDS.bytes) total += (value.length - 2) / 2;
	if (total > MAX_ENTITY_BYTES) throw new EntityTooLargeError(total, MAX_ENTITY_BYTES);
}
/**
* The engine requires attributes **strictly ascending by their `bytes32` name**: that ordering is
* what the canonical serialization hashes into the state root, and it doubles as the uniqueness
* check.
*/
function byName(a, b) {
	return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
}

//#endregion
Object.defineProperty(exports, 'ConflictingMutationError', {
  enumerable: true,
  get: function () {
    return ConflictingMutationError;
  }
});
Object.defineProperty(exports, 'DECIMAL_SCALE', {
  enumerable: true,
  get: function () {
    return DECIMAL_SCALE;
  }
});
Object.defineProperty(exports, 'DECIMAL_UNIT', {
  enumerable: true,
  get: function () {
    return DECIMAL_UNIT;
  }
});
Object.defineProperty(exports, 'EntityTooLargeError', {
  enumerable: true,
  get: function () {
    return EntityTooLargeError;
  }
});
Object.defineProperty(exports, 'I32_MAX', {
  enumerable: true,
  get: function () {
    return I32_MAX;
  }
});
Object.defineProperty(exports, 'I32_MIN', {
  enumerable: true,
  get: function () {
    return I32_MIN;
  }
});
Object.defineProperty(exports, 'INDEXED_FLAG', {
  enumerable: true,
  get: function () {
    return INDEXED_FLAG;
  }
});
Object.defineProperty(exports, 'InvalidAttributeNameError', {
  enumerable: true,
  get: function () {
    return InvalidAttributeNameError;
  }
});
Object.defineProperty(exports, 'InvalidValueError', {
  enumerable: true,
  get: function () {
    return InvalidValueError;
  }
});
Object.defineProperty(exports, 'MAX_ATTRIBUTES', {
  enumerable: true,
  get: function () {
    return MAX_ATTRIBUTES;
  }
});
Object.defineProperty(exports, 'MAX_BYTES_LENGTH', {
  enumerable: true,
  get: function () {
    return MAX_BYTES_LENGTH;
  }
});
Object.defineProperty(exports, 'MAX_ENTITY_BYTES', {
  enumerable: true,
  get: function () {
    return MAX_ENTITY_BYTES;
  }
});
Object.defineProperty(exports, 'MAX_NAME_BYTES', {
  enumerable: true,
  get: function () {
    return MAX_NAME_BYTES;
  }
});
Object.defineProperty(exports, 'MAX_STRING_BYTES', {
  enumerable: true,
  get: function () {
    return MAX_STRING_BYTES;
  }
});
Object.defineProperty(exports, 'MissingValueError', {
  enumerable: true,
  get: function () {
    return MissingValueError;
  }
});
Object.defineProperty(exports, 'SCHEMA_ATTRIBUTE', {
  enumerable: true,
  get: function () {
    return SCHEMA_ATTRIBUTE;
  }
});
Object.defineProperty(exports, 'SchemaDefinitionError', {
  enumerable: true,
  get: function () {
    return SchemaDefinitionError;
  }
});
Object.defineProperty(exports, 'SchemaMismatchError', {
  enumerable: true,
  get: function () {
    return SchemaMismatchError;
  }
});
Object.defineProperty(exports, 'TYPE_IDS', {
  enumerable: true,
  get: function () {
    return TYPE_IDS;
  }
});
Object.defineProperty(exports, 'TooManyAttributesError', {
  enumerable: true,
  get: function () {
    return TooManyAttributesError;
  }
});
Object.defineProperty(exports, 'U256_MAX', {
  enumerable: true,
  get: function () {
    return U256_MAX;
  }
});
Object.defineProperty(exports, 'U64_MAX', {
  enumerable: true,
  get: function () {
    return U64_MAX;
  }
});
Object.defineProperty(exports, 'UnknownAttributeTypeError', {
  enumerable: true,
  get: function () {
    return UnknownAttributeTypeError;
  }
});
Object.defineProperty(exports, 'UntypedValueError', {
  enumerable: true,
  get: function () {
    return UntypedValueError;
  }
});
Object.defineProperty(exports, 'addr', {
  enumerable: true,
  get: function () {
    return addr;
  }
});
Object.defineProperty(exports, 'asTypeTag', {
  enumerable: true,
  get: function () {
    return asTypeTag;
  }
});
Object.defineProperty(exports, 'bool', {
  enumerable: true,
  get: function () {
    return bool;
  }
});
Object.defineProperty(exports, 'bytes', {
  enumerable: true,
  get: function () {
    return bytes;
  }
});
Object.defineProperty(exports, 'dec', {
  enumerable: true,
  get: function () {
    return dec;
  }
});
Object.defineProperty(exports, 'decFromUnits', {
  enumerable: true,
  get: function () {
    return decFromUnits;
  }
});
Object.defineProperty(exports, 'decUnits', {
  enumerable: true,
  get: function () {
    return decUnits;
  }
});
Object.defineProperty(exports, 'decodeRpcValue', {
  enumerable: true,
  get: function () {
    return decodeRpcValue;
  }
});
Object.defineProperty(exports, 'decodeTypeId', {
  enumerable: true,
  get: function () {
    return decodeTypeId;
  }
});
Object.defineProperty(exports, 'defineSchema', {
  enumerable: true,
  get: function () {
    return defineSchema;
  }
});
Object.defineProperty(exports, 'describeColumns', {
  enumerable: true,
  get: function () {
    return describeColumns;
  }
});
Object.defineProperty(exports, 'encodeCreate', {
  enumerable: true,
  get: function () {
    return encodeCreate;
  }
});
Object.defineProperty(exports, 'encodePatch', {
  enumerable: true,
  get: function () {
    return encodePatch;
  }
});
Object.defineProperty(exports, 'i32', {
  enumerable: true,
  get: function () {
    return i32;
  }
});
Object.defineProperty(exports, 'isArkivValue', {
  enumerable: true,
  get: function () {
    return isArkivValue;
  }
});
Object.defineProperty(exports, 'isColumn', {
  enumerable: true,
  get: function () {
    return isColumn;
  }
});
Object.defineProperty(exports, 'isIndexable', {
  enumerable: true,
  get: function () {
    return isIndexable;
  }
});
Object.defineProperty(exports, 'isSchema', {
  enumerable: true,
  get: function () {
    return isSchema;
  }
});
Object.defineProperty(exports, 'isValidAttributeName', {
  enumerable: true,
  get: function () {
    return isValidAttributeName;
  }
});
Object.defineProperty(exports, 'key', {
  enumerable: true,
  get: function () {
    return key;
  }
});
Object.defineProperty(exports, 'lookupColumn', {
  enumerable: true,
  get: function () {
    return lookupColumn;
  }
});
Object.defineProperty(exports, 'str', {
  enumerable: true,
  get: function () {
    return str;
  }
});
Object.defineProperty(exports, 'toValue', {
  enumerable: true,
  get: function () {
    return toValue;
  }
});
Object.defineProperty(exports, 'u256', {
  enumerable: true,
  get: function () {
    return u256;
  }
});
Object.defineProperty(exports, 'u64', {
  enumerable: true,
  get: function () {
    return u64;
  }
});
Object.defineProperty(exports, 'validateAttributeName', {
  enumerable: true,
  get: function () {
    return validateAttributeName;
  }
});