@arkiv-network/sdk 0.8.0-dev.1 → 0.8.0-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attr/index.cjs +1 -1
- package/dist/attr/index.d.cts +1 -1
- package/dist/attr/index.d.ts +1 -1
- package/dist/attr/index.js +1 -1
- package/dist/{attr-BvxHN99W.cjs → attr-BXTkpnoc.cjs} +13 -3
- package/dist/{attr-BDZ-APg5.js → attr-tmyREHtw.js} +14 -4
- package/dist/attr-tmyREHtw.js.map +1 -0
- package/dist/chains/index.cjs +1 -1
- package/dist/chains/index.d.cts +3 -0
- package/dist/chains/index.d.cts.map +1 -1
- package/dist/chains/index.d.ts +3 -0
- package/dist/chains/index.d.ts.map +1 -1
- package/dist/chains/index.js +1 -1
- package/dist/{chains-BYRTTipa.cjs → chains-BfNQliHU.cjs} +3 -0
- package/dist/{chains-BJrZs6sG.js → chains-Du8tql7I.js} +4 -1
- package/dist/chains-Du8tql7I.js.map +1 -0
- package/dist/{changeOwnership-DwgtdSFc.d.ts → changeOwnership-B0ar96ub.d.ts} +47 -34
- package/dist/changeOwnership-B0ar96ub.d.ts.map +1 -0
- package/dist/{changeOwnership-B7bEgla4.d.cts → changeOwnership-BofkLnXJ.d.cts} +47 -34
- package/dist/changeOwnership-BofkLnXJ.d.cts.map +1 -0
- package/dist/entity/index.cjs +5 -4
- package/dist/entity/index.d.cts +2 -2
- package/dist/entity/index.d.ts +2 -2
- package/dist/entity/index.js +5 -5
- package/dist/{entity-CFhbAv0R.js → entity-CniBgBSd.js} +17 -5
- package/dist/entity-CniBgBSd.js.map +1 -0
- package/dist/{entity-wfBnZd91.cjs → entity-DJ0Gml9c.cjs} +23 -5
- package/dist/{errors-DGB8AgT2.js → errors-D2E1GRjw.js} +2 -2
- package/dist/errors-D2E1GRjw.js.map +1 -0
- package/dist/{errors-D-eJkGVc.cjs → errors-DhV00966.cjs} +1 -1
- package/dist/expiry-BxOlvVWC.d.ts.map +1 -1
- package/dist/{expiry-BUYIXTGb.cjs → expiry-CG9GhVXv.cjs} +1 -1
- package/dist/{expiry-DGRzrSan.js → expiry-Cgdb_dbq.js} +2 -2
- package/dist/expiry-Cgdb_dbq.js.map +1 -0
- package/dist/expiry-DRV29F1r.d.cts.map +1 -1
- package/dist/{flags-Ct8k0gpB.cjs → flags-DCD26uhe.cjs} +1 -1
- package/dist/{flags-ZtlvOIIk.js → flags-DUT2gHEU.js} +2 -2
- package/dist/{flags-ZtlvOIIk.js.map → flags-DUT2gHEU.js.map} +1 -1
- package/dist/{index-D0CmtiWT.d.cts → index-BGp2plHs.d.cts} +15 -5
- package/dist/index-BGp2plHs.d.cts.map +1 -0
- package/dist/{index-VCqgn29D.d.ts → index-BKB875Um.d.ts} +4 -4
- package/dist/{index-VCqgn29D.d.ts.map → index-BKB875Um.d.ts.map} +1 -1
- package/dist/{index-DVYFaXNV.d.ts → index-CIcHPx2j.d.cts} +13 -6
- package/dist/index-CIcHPx2j.d.cts.map +1 -0
- package/dist/{index-D8LZt-3J.d.cts → index-Cd2aaWme.d.ts} +13 -6
- package/dist/index-Cd2aaWme.d.ts.map +1 -0
- package/dist/{index-ClgIuxJ8.d.ts → index-ezMZ2-JH.d.ts} +15 -5
- package/dist/index-ezMZ2-JH.d.ts.map +1 -0
- package/dist/{index-Cgw1u5aY.d.cts → index-rINthNuU.d.cts} +4 -4
- package/dist/{index-Cgw1u5aY.d.cts.map → index-rINthNuU.d.cts.map} +1 -1
- package/dist/index.cjs +59 -50
- package/dist/index.d.cts +58 -50
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +58 -50
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +59 -51
- package/dist/index.js.map +1 -1
- package/dist/{payload-Dgx3PQeK.d.ts → payload-CGvVPZQX.d.ts} +60 -1
- package/dist/payload-CGvVPZQX.d.ts.map +1 -0
- package/dist/{payload-CIxSn_DW.js → payload-DE7wMztL.js} +28 -3
- package/dist/payload-DE7wMztL.js.map +1 -0
- package/dist/{payload-P0nWyjLg.d.cts → payload-Dfu30njp.d.cts} +60 -1
- package/dist/payload-Dfu30njp.d.cts.map +1 -0
- package/dist/{payload-Bnw1hrvb.cjs → payload-DqFweqiO.cjs} +27 -2
- package/dist/query/index.cjs +4 -4
- package/dist/query/index.d.cts +3 -3
- package/dist/query/index.d.ts +3 -3
- package/dist/query/index.js +4 -4
- package/dist/{queryBuilder-CbLL4pG5.js → queryBuilder-COWt6aIF.js} +17 -12
- package/dist/queryBuilder-COWt6aIF.js.map +1 -0
- package/dist/{queryBuilder-BXDvX1K_.cjs → queryBuilder-DaLxNgeI.cjs} +16 -11
- package/dist/{selection-BvK6yX0g.d.cts → selection-Bv8_o-7i.d.cts} +16 -8
- package/dist/selection-Bv8_o-7i.d.cts.map +1 -0
- package/dist/{selection-fpmI3ADQ.d.ts → selection-ox7zdtVm.d.ts} +16 -8
- package/dist/selection-ox7zdtVm.d.ts.map +1 -0
- package/dist/types/index.d.cts +5 -5
- package/dist/types/index.d.ts +5 -5
- package/dist/utils/index.cjs +3 -3
- package/dist/utils/index.d.cts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +3 -3
- package/package.json +1 -5
- package/src/actions/public/getEntity.ts +1 -0
- package/src/actions/public/predictEntityKeys.test.ts +17 -1
- package/src/actions/public/predictEntityKeys.ts +28 -14
- package/src/actions/wallet/createEntity.ts +8 -6
- package/src/actions/wallet/{mutateEntities.test.ts → executeBatch.test.ts} +7 -7
- package/src/actions/wallet/{mutateEntities.ts → executeBatch.ts} +9 -9
- package/src/actions/wallet/extendEntity.ts +2 -0
- package/src/actions/wallet/patchEntity.ts +3 -3
- package/src/attr/attributes.ts +8 -2
- package/src/attr/errors.ts +2 -2
- package/src/attr/types.ts +3 -3
- package/src/attr/values.ts +5 -1
- package/src/chains/localhost.ts +3 -0
- package/src/clients/createPublicClient.test.ts +1 -1
- package/src/clients/createPublicClient.ts +5 -5
- package/src/clients/createWalletClient.test.ts +2 -2
- package/src/clients/createWalletClient.ts +3 -5
- package/src/clients/decorators/arkivPublic.ts +13 -12
- package/src/clients/decorators/arkivWallet.ts +40 -32
- package/src/entity/create.test.ts +20 -1
- package/src/entity/errors.ts +4 -3
- package/src/entity/expiry.ts +1 -0
- package/src/entity/index.ts +2 -1
- package/src/entity/key.ts +23 -3
- package/src/entity/operations.ts +1 -0
- package/src/errors.ts +7 -2
- package/src/query/errors.ts +1 -1
- package/src/query/expression.ts +14 -7
- package/src/query/queryBuilder.ts +1 -1
- package/src/types/index.ts +4 -4
- package/src/types/rpcSchema.ts +1 -0
- package/src/types/txParams.ts +8 -0
- package/src/utils/arkivTransactions.test.ts +7 -1
- package/src/utils/arkivTransactions.ts +10 -5
- package/src/utils/expirationTime.ts +39 -0
- package/src/utils/payload.ts +25 -0
- package/dist/attr-BDZ-APg5.js.map +0 -1
- package/dist/chains-BJrZs6sG.js.map +0 -1
- package/dist/changeOwnership-B7bEgla4.d.cts.map +0 -1
- package/dist/changeOwnership-DwgtdSFc.d.ts.map +0 -1
- package/dist/entity-CFhbAv0R.js.map +0 -1
- package/dist/errors-DGB8AgT2.js.map +0 -1
- package/dist/expiry-DGRzrSan.js.map +0 -1
- package/dist/index-ClgIuxJ8.d.ts.map +0 -1
- package/dist/index-D0CmtiWT.d.cts.map +0 -1
- package/dist/index-D8LZt-3J.d.cts.map +0 -1
- package/dist/index-DVYFaXNV.d.ts.map +0 -1
- package/dist/payload-CIxSn_DW.js.map +0 -1
- package/dist/payload-Dgx3PQeK.d.ts.map +0 -1
- package/dist/payload-P0nWyjLg.d.cts.map +0 -1
- package/dist/queryBuilder-CbLL4pG5.js.map +0 -1
- package/dist/selection-BvK6yX0g.d.cts.map +0 -1
- package/dist/selection-fpmI3ADQ.d.ts.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from "bun:test"
|
|
2
2
|
import type { ArkivClient } from "../../clients/baseClient"
|
|
3
|
-
import {
|
|
3
|
+
import { executeBatch } from "./executeBatch"
|
|
4
4
|
|
|
5
5
|
const ENTITY_KEY = `0x${"ab".repeat(32)}` as const
|
|
6
6
|
const NEW_OWNER = "0x2222222222222222222222222222222222222222"
|
|
@@ -29,7 +29,7 @@ describe("the empty-batch guard", () => {
|
|
|
29
29
|
// An ownership-only batch is a batch: it used to be rejected because the guard listed
|
|
30
30
|
// creates/updates/deletes/extensions and forgot ownershipChanges.
|
|
31
31
|
const { client, writeContract } = makeClient()
|
|
32
|
-
const result = await
|
|
32
|
+
const result = await executeBatch(client, {
|
|
33
33
|
ownershipChanges: [{ entityKey: ENTITY_KEY, newOwner: NEW_OWNER }],
|
|
34
34
|
})
|
|
35
35
|
expect(writeContract).toHaveBeenCalledTimes(1)
|
|
@@ -38,9 +38,9 @@ describe("the empty-batch guard", () => {
|
|
|
38
38
|
|
|
39
39
|
it("rejects a batch with nothing in it", async () => {
|
|
40
40
|
const { client, writeContract } = makeClient()
|
|
41
|
-
await expect(
|
|
41
|
+
await expect(executeBatch(client, {})).rejects.toThrow(/No operations/)
|
|
42
42
|
// Present but empty is just as empty — the engine would revert with EmptyBatch().
|
|
43
|
-
await expect(
|
|
43
|
+
await expect(executeBatch(client, { deletes: [], ownershipChanges: [] })).rejects.toThrow(
|
|
44
44
|
/No operations/,
|
|
45
45
|
)
|
|
46
46
|
expect(writeContract).not.toHaveBeenCalled()
|
|
@@ -52,10 +52,10 @@ describe("the empty-batch guard", () => {
|
|
|
52
52
|
// keys would score this batch as non-empty and then drop it on the way to the wire, sending
|
|
53
53
|
// execute([]) — so the guard counts the five kinds that actually reach the transaction.
|
|
54
54
|
const stale = { updates: [{ entityKey: ENTITY_KEY, set: { level: 1 } }] } as never
|
|
55
|
-
await expect(
|
|
55
|
+
await expect(executeBatch(client, stale)).rejects.toThrow(/No operations/)
|
|
56
56
|
// A typo is the same mistake with a different name.
|
|
57
57
|
await expect(
|
|
58
|
-
|
|
58
|
+
executeBatch(client, { delete: [{ entityKey: ENTITY_KEY }] } as never),
|
|
59
59
|
).rejects.toThrow(/No operations/)
|
|
60
60
|
expect(writeContract).not.toHaveBeenCalled()
|
|
61
61
|
})
|
|
@@ -65,7 +65,7 @@ describe("the empty-batch guard", () => {
|
|
|
65
65
|
// The dangerous shape: the creates apply and the transaction succeeds, so nothing surfaces the
|
|
66
66
|
// fact that the `updates` never happened. The guard cannot catch this one — only the caller's
|
|
67
67
|
// types can — but the result must at least not claim they did.
|
|
68
|
-
const result = await
|
|
68
|
+
const result = await executeBatch(client, {
|
|
69
69
|
deletes: [{ entityKey: ENTITY_KEY }],
|
|
70
70
|
updates: [{ entityKey: ENTITY_KEY, set: { level: 1 } }],
|
|
71
71
|
} as never)
|
|
@@ -9,15 +9,15 @@ import type { DeleteEntityParameters } from "./deleteEntity"
|
|
|
9
9
|
import type { ExtendEntityParameters } from "./extendEntity"
|
|
10
10
|
import type { PatchEntityParameters } from "./patchEntity"
|
|
11
11
|
|
|
12
|
-
const logger = getLogger("actions:wallet:
|
|
12
|
+
const logger = getLogger("actions:wallet:execute-batch")
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Parameters for the
|
|
15
|
+
* Parameters for the executeBatch function.
|
|
16
16
|
*
|
|
17
17
|
* At least one operation is required; a batch with nothing in it throws rather than spending gas on
|
|
18
18
|
* an empty transaction.
|
|
19
19
|
*/
|
|
20
|
-
export type
|
|
20
|
+
export type ExecuteBatchParameters = {
|
|
21
21
|
/** The entities to create. */
|
|
22
22
|
creates?: CreateEntityParameters[]
|
|
23
23
|
/** The patches to apply. */
|
|
@@ -30,8 +30,8 @@ export type MutateEntitiesParameters = {
|
|
|
30
30
|
ownershipChanges?: ChangeOwnershipParameters[]
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/** Return type for the
|
|
34
|
-
export type
|
|
33
|
+
/** Return type for the executeBatch function. */
|
|
34
|
+
export type ExecuteBatchReturnType = {
|
|
35
35
|
/** The transaction hash. */
|
|
36
36
|
txHash: Hash
|
|
37
37
|
/** The keys of the created entities, in batch order. */
|
|
@@ -46,14 +46,14 @@ export type MutateEntitiesReturnType = {
|
|
|
46
46
|
ownershipChanges: Hex[]
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export async function
|
|
49
|
+
export async function executeBatch(
|
|
50
50
|
client: ArkivClient,
|
|
51
|
-
data:
|
|
51
|
+
data: ExecuteBatchParameters,
|
|
52
52
|
txParams?: TxParams,
|
|
53
|
-
): Promise<
|
|
53
|
+
): Promise<ExecuteBatchReturnType> {
|
|
54
54
|
const { receipt, createdEntityKeys } = await sendArkivTransaction(client, data, txParams)
|
|
55
55
|
|
|
56
|
-
logger("Receipt from
|
|
56
|
+
logger("Receipt from executeBatch %o", receipt)
|
|
57
57
|
|
|
58
58
|
return {
|
|
59
59
|
txHash: receipt.transactionHash as Hash,
|
|
@@ -4,6 +4,7 @@ import type { Expiry } from "../../entity"
|
|
|
4
4
|
import { EntityMutationError } from "../../errors"
|
|
5
5
|
import type { TxParams } from "../../types"
|
|
6
6
|
import { sendArkivTransaction } from "../../utils/arkivTransactions"
|
|
7
|
+
import type { ExpirationTime } from "../../utils/expirationTime"
|
|
7
8
|
import { getLogger } from "../../utils/logger"
|
|
8
9
|
|
|
9
10
|
const logger = getLogger("actions:wallet:extend-entity")
|
|
@@ -61,6 +62,7 @@ export async function extendEntity(
|
|
|
61
62
|
if (expiresAt === undefined) {
|
|
62
63
|
throw new EntityMutationError(
|
|
63
64
|
`Transaction ${receipt.transactionHash} succeeded, but the receipt did not carry the expected entity expiry.`,
|
|
65
|
+
{ txHash: receipt.transactionHash },
|
|
64
66
|
)
|
|
65
67
|
}
|
|
66
68
|
|
|
@@ -38,9 +38,9 @@ export type PatchEntityParameters = {
|
|
|
38
38
|
* Attributes to write, keyed by name. An existing attribute is overwritten — including with a
|
|
39
39
|
* different type — and a name the entity does not carry yet is added.
|
|
40
40
|
*
|
|
41
|
-
* Values are the tagged constructors from `@arkiv-network/sdk/attr` — `i32`, `
|
|
42
|
-
* `addr`, `key`, `bytes32`, `bool` — or a bare `boolean`, `number`, `bigint` or
|
|
43
|
-
* type is unambiguous.
|
|
41
|
+
* Values are the tagged constructors from `@arkiv-network/sdk/attr` — `i32`, `u64`, `u256`,
|
|
42
|
+
* `dec`, `str`, `addr`, `key`, `bytes32`, `bool` — or a bare `boolean`, `number`, `bigint` or
|
|
43
|
+
* `string` where the type is unambiguous.
|
|
44
44
|
*
|
|
45
45
|
* @throws {InvalidAttributeNameError} If a name violates the attribute-name grammar.
|
|
46
46
|
* @throws {InvalidValueError} If a value does not fit the type it names or defaults to.
|
package/src/attr/attributes.ts
CHANGED
|
@@ -10,6 +10,10 @@ import { str, toValue, type ValueInput } from "./values"
|
|
|
10
10
|
*/
|
|
11
11
|
export const MAX_ATTRIBUTES = 32
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* The largest payload an entity may carry, in bytes. The payload travels as the `$payload` system
|
|
15
|
+
* cell, so this is a bound on that one attribute rather than on the operation as a whole.
|
|
16
|
+
*/
|
|
13
17
|
export const MAX_PAYLOAD_BYTES = 128 * 1024
|
|
14
18
|
|
|
15
19
|
/** The system attribute holding an entity's opaque payload. */
|
|
@@ -20,7 +24,7 @@ const CONTENT_TYPE_CELL = "$contentType"
|
|
|
20
24
|
/**
|
|
21
25
|
* The attributes written on an entity, as a plain object keyed by attribute name.
|
|
22
26
|
*
|
|
23
|
-
* Values may be tagged ({@link
|
|
27
|
+
* Values may be tagged ({@link ArkivValue}) or bare where the type is unambiguous — see
|
|
24
28
|
* {@link toValue} for the bare-form defaults.
|
|
25
29
|
*
|
|
26
30
|
* @example
|
|
@@ -141,8 +145,10 @@ export type MutationInputs = SystemCells & {
|
|
|
141
145
|
*
|
|
142
146
|
* @throws {ConflictingMutationError} If a name appears in both `set` and `unset`.
|
|
143
147
|
* @throws {InvalidAttributeNameError} If a name violates the attribute-name grammar.
|
|
148
|
+
* @throws {MissingValueError} If a value is `undefined` or `null`.
|
|
144
149
|
* @throws {InvalidValueError} If a value does not fit its type.
|
|
145
|
-
* @throws {TooManyAttributesError} If
|
|
150
|
+
* @throws {TooManyAttributesError} If the mutations exceed {@link MAX_ATTRIBUTES}.
|
|
151
|
+
* @throws {TypeError} If `unset` is not an array.
|
|
146
152
|
*/
|
|
147
153
|
export function encodeMutations({
|
|
148
154
|
set,
|
package/src/attr/errors.ts
CHANGED
|
@@ -32,8 +32,8 @@ export class UntypedValueError extends Error {
|
|
|
32
32
|
constructor(input: unknown) {
|
|
33
33
|
super(
|
|
34
34
|
`Cannot infer an Arkiv type for ${describe(input)}. ` +
|
|
35
|
-
"Attribute values must be a tagged value (i32, u256, dec, str, addr, key, bytes32,
|
|
36
|
-
"or a bare boolean, number, bigint or string.",
|
|
35
|
+
"Attribute values must be a tagged value (i32, u64, u256, dec, str, addr, key, bytes32, " +
|
|
36
|
+
"bool) or a bare boolean, number, bigint or string.",
|
|
37
37
|
)
|
|
38
38
|
this.name = "UntypedValueError"
|
|
39
39
|
this.input = input
|
package/src/attr/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Address, Hex } from "viem"
|
|
2
|
+
import type { decUnits } from "./values"
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* The protocol's attribute type vocabulary, mapping each short **tag** (the name used by the
|
|
@@ -54,8 +55,7 @@ export function isUserSettable(tag: TypeTag): tag is UserTypeTag {
|
|
|
54
55
|
/**
|
|
55
56
|
* Marks a value as having passed its constructor's validation. The symbol is module-private, so a
|
|
56
57
|
* hand-written object literal is not assignable to {@link ArkivValue} — every value crossing the
|
|
57
|
-
* wire has been range-, length- and format-checked by
|
|
58
|
-
* friends.
|
|
58
|
+
* wire has been range-, length- and format-checked by `i32`, `u256`, `dec`, and friends.
|
|
59
59
|
*/
|
|
60
60
|
declare const validated: unique symbol
|
|
61
61
|
|
|
@@ -89,7 +89,7 @@ export type U256Value = Value<"u256", bigint>
|
|
|
89
89
|
export type DecValue = Value<"dec", string>
|
|
90
90
|
/** 32 opaque bytes, as lowercase `0x` hex. */
|
|
91
91
|
export type Bytes32Value = Value<"bytes32", Hex>
|
|
92
|
-
/** A UTF-8 string of at most 128 bytes. */
|
|
92
|
+
/** A UTF-8 string of at most 128 bytes, free of C0 control characters and DEL. */
|
|
93
93
|
export type StrValue = Value<"str", string>
|
|
94
94
|
/** A 20-byte Ethereum address, as EIP-55 checksummed hex. */
|
|
95
95
|
export type AddrValue = Value<"addr", Address>
|
package/src/attr/values.ts
CHANGED
|
@@ -271,7 +271,11 @@ export function decFromUnits(units: bigint): DecValue {
|
|
|
271
271
|
*
|
|
272
272
|
* The limit is on **bytes**, not characters: a string of 128 emoji does not fit.
|
|
273
273
|
*
|
|
274
|
-
*
|
|
274
|
+
* C0 control characters and DEL are rejected: the query language writes a `str` as `str('...')`,
|
|
275
|
+
* whose only escape is a doubled quote, so a control character could be stored but never queried.
|
|
276
|
+
*
|
|
277
|
+
* @throws {InvalidValueError} If the value is not a string, holds a control character, or exceeds
|
|
278
|
+
* 128 UTF-8 bytes.
|
|
275
279
|
*
|
|
276
280
|
* @example
|
|
277
281
|
* str("Bob")
|
package/src/chains/localhost.ts
CHANGED
|
@@ -35,5 +35,5 @@ test("creates", () => {
|
|
|
35
35
|
expect(client.deleteEntity).not.toBeDefined()
|
|
36
36
|
expect(client.extendEntity).not.toBeDefined()
|
|
37
37
|
expect(client.changeOwnership).not.toBeDefined()
|
|
38
|
-
expect(client.
|
|
38
|
+
expect(client.executeBatch).not.toBeDefined()
|
|
39
39
|
})
|
|
@@ -23,14 +23,14 @@ export type PublicArkivClient<
|
|
|
23
23
|
>
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* Creates a Public Client with a given [Transport](https://viem.sh/docs/clients/intro) configured for a [Chain](https://viem.sh/docs/
|
|
26
|
+
* Creates a Public Client with a given [Transport](https://viem.sh/docs/clients/intro) configured for a [Chain](https://viem.sh/docs/chains/introduction).
|
|
27
27
|
*
|
|
28
|
-
* -
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* A Public Client is an interface to the "public" [Ethereum JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/)
|
|
29
|
+
* and the Arkiv JSON-RPC API — retrieving block numbers and transactions, reading from
|
|
30
|
+
* contracts, and querying entities — through {@link PublicArkivActions}.
|
|
31
31
|
*
|
|
32
32
|
* @param parameters - Configuration object for the public client (chain, transport, etc.)
|
|
33
|
-
* @returns
|
|
33
|
+
* @returns An Arkiv Public Client. {@link PublicArkivClient}
|
|
34
34
|
*
|
|
35
35
|
* @example
|
|
36
36
|
* import { createPublicClient } from "@arkiv-network/sdk"
|
|
@@ -29,6 +29,6 @@ test("creates", () => {
|
|
|
29
29
|
expect(typeof client.extendEntity).toBe("function")
|
|
30
30
|
expect(client.changeOwnership).toBeDefined()
|
|
31
31
|
expect(typeof client.changeOwnership).toBe("function")
|
|
32
|
-
expect(client.
|
|
33
|
-
expect(typeof client.
|
|
32
|
+
expect(client.executeBatch).toBeDefined()
|
|
33
|
+
expect(typeof client.executeBatch).toBe("function")
|
|
34
34
|
})
|
|
@@ -24,16 +24,14 @@ export type WalletArkivClient<
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Creates a Wallet Client with a given [Transport](https://viem.sh/docs/clients/intro) configured
|
|
27
|
-
* for a [Chain](https://viem.sh/docs/
|
|
28
|
-
*
|
|
29
|
-
* - Docs: https://docs.arkiv.network/ts-sdk/clients/wallet
|
|
27
|
+
* for a [Chain](https://viem.sh/docs/chains/introduction) and an account.
|
|
30
28
|
*
|
|
31
29
|
* A Wallet Client signs and sends transactions, so it carries an `account` and exposes everything
|
|
32
30
|
* that mutates state — `createEntity`, `patchEntity`, `deleteEntity`, `extendEntity`,
|
|
33
|
-
* `changeOwnership` and `
|
|
31
|
+
* `changeOwnership` and `executeBatch` — on top of the read actions a Public Client has.
|
|
34
32
|
*
|
|
35
33
|
* @param parameters - Configuration object for the wallet client (chain, transport, account, etc.)
|
|
36
|
-
* @returns
|
|
34
|
+
* @returns An Arkiv Wallet Client. {@link WalletArkivClient}
|
|
37
35
|
*
|
|
38
36
|
* @example
|
|
39
37
|
* import { createWalletClient } from "@arkiv-network/sdk"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Account, Address, Chain, Client, Hex, PublicActions, Transport } from "viem"
|
|
2
|
-
import { getBlockTiming } from "../../actions/public/getBlockTiming"
|
|
2
|
+
import { type GetBlockTimingReturnType, getBlockTiming } from "../../actions/public/getBlockTiming"
|
|
3
3
|
import { getEntity } from "../../actions/public/getEntity"
|
|
4
4
|
import { getEntityCount } from "../../actions/public/getEntityCount"
|
|
5
5
|
import { getEntityNonce } from "../../actions/public/getEntityNonce"
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
type WatchEntityEventsParameters,
|
|
14
14
|
watchEntityEvents,
|
|
15
15
|
} from "../../actions/public/watchEntityEvents"
|
|
16
|
+
import type { SaltInput } from "../../entity/key"
|
|
16
17
|
import type { Expression } from "../../query/expression"
|
|
17
18
|
import { SelectQueryBuilder } from "../../query/queryBuilder"
|
|
18
19
|
import type { EntitySelection, FullEntity, ProjectedEntity, SelectArg } from "../../query/selection"
|
|
@@ -38,11 +39,15 @@ export type PublicArkivActions<
|
|
|
38
39
|
/**
|
|
39
40
|
* Returns the entity with the given key.
|
|
40
41
|
*
|
|
41
|
-
* -
|
|
42
|
+
* - JSON-RPC Methods: `arkiv_query`
|
|
42
43
|
*
|
|
43
44
|
* @param key - The entity key (hex string)
|
|
44
45
|
* @returns The entity with the given key, with every field populated. {@link FullEntity}
|
|
45
46
|
*
|
|
47
|
+
* @throws {InvalidValueError} If the key is not 32 bytes.
|
|
48
|
+
* @throws {NoEntityFoundError} If no live entity has that key — it never existed, or it was
|
|
49
|
+
* deleted or has expired.
|
|
50
|
+
*
|
|
46
51
|
* @example
|
|
47
52
|
* import { createPublicClient } from "@arkiv-network/sdk"
|
|
48
53
|
* import { cheesecake } from "@arkiv-network/sdk/chains"
|
|
@@ -69,7 +74,7 @@ export type PublicArkivActions<
|
|
|
69
74
|
* read entities. You declare up front which parts of an entity you want returned, so results
|
|
70
75
|
* always contain exactly the data you asked for.
|
|
71
76
|
*
|
|
72
|
-
* -
|
|
77
|
+
* - JSON-RPC Methods: `arkiv_query`
|
|
73
78
|
*
|
|
74
79
|
* @param selection - What to include in the results. Omit it (or pass `"*"`) to select everything,
|
|
75
80
|
* or pass an object to select specific parts (at least one field is required). Every part is
|
|
@@ -130,7 +135,7 @@ export type PublicArkivActions<
|
|
|
130
135
|
/**
|
|
131
136
|
* Runs one query and returns one page, with no builder in between.
|
|
132
137
|
*
|
|
133
|
-
* Use {@link select} for anything typed — this returns full {@link Entity} objects whatever the
|
|
138
|
+
* Use {@link PublicArkivActions.select} for anything typed — this returns full {@link Entity} objects whatever the
|
|
134
139
|
* selection, and takes a raw string as an escape hatch for a query built elsewhere. A raw string
|
|
135
140
|
* goes to the node exactly as written, with none of the name, type or operator checks the
|
|
136
141
|
* expression combinators apply.
|
|
@@ -224,7 +229,7 @@ export type PublicArkivActions<
|
|
|
224
229
|
* import { key } from "@arkiv-network/sdk/attr"
|
|
225
230
|
*
|
|
226
231
|
* const [parent, child] = await client.predictEntityKeys({ owner: account.address, count: 2 })
|
|
227
|
-
* await wallet.
|
|
232
|
+
* await wallet.executeBatch({
|
|
228
233
|
* creates: [
|
|
229
234
|
* { payload, contentType, expires, salt: parent.salt },
|
|
230
235
|
* {
|
|
@@ -239,7 +244,7 @@ export type PublicArkivActions<
|
|
|
239
244
|
*/
|
|
240
245
|
predictEntityKeys: <
|
|
241
246
|
const TCount extends number = number,
|
|
242
|
-
const TSalts extends readonly
|
|
247
|
+
const TSalts extends readonly SaltInput[] | undefined = undefined,
|
|
243
248
|
>(
|
|
244
249
|
parameters: PredictEntityKeysParameters<TCount, TSalts>,
|
|
245
250
|
) => Promise<PredictEntityKeysReturnType<TCount, TSalts>>
|
|
@@ -264,11 +269,7 @@ export type PublicArkivActions<
|
|
|
264
269
|
* // blockDuration: 2, // in seconds
|
|
265
270
|
* // }
|
|
266
271
|
*/
|
|
267
|
-
getBlockTiming: () => Promise<
|
|
268
|
-
currentBlock: bigint
|
|
269
|
-
currentBlockTime: number
|
|
270
|
-
blockDuration: number
|
|
271
|
-
}>
|
|
272
|
+
getBlockTiming: () => Promise<GetBlockTimingReturnType>
|
|
272
273
|
|
|
273
274
|
/**
|
|
274
275
|
* Watches entity events, calling the handlers you pass as they arrive.
|
|
@@ -314,7 +315,7 @@ export function publicArkivActions<
|
|
|
314
315
|
getEntityNonce: (owner: Address) => getEntityNonce(client, owner),
|
|
315
316
|
predictEntityKeys: <
|
|
316
317
|
const TCount extends number = number,
|
|
317
|
-
const TSalts extends readonly
|
|
318
|
+
const TSalts extends readonly SaltInput[] | undefined = undefined,
|
|
318
319
|
>(
|
|
319
320
|
parameters: PredictEntityKeysParameters<TCount, TSalts>,
|
|
320
321
|
) => predictEntityKeys(client, parameters),
|
|
@@ -14,16 +14,16 @@ import type {
|
|
|
14
14
|
DeleteEntityReturnType,
|
|
15
15
|
} from "../../actions/wallet/deleteEntity"
|
|
16
16
|
import { deleteEntity } from "../../actions/wallet/deleteEntity"
|
|
17
|
+
import type {
|
|
18
|
+
ExecuteBatchParameters,
|
|
19
|
+
ExecuteBatchReturnType,
|
|
20
|
+
} from "../../actions/wallet/executeBatch"
|
|
21
|
+
import { executeBatch } from "../../actions/wallet/executeBatch"
|
|
17
22
|
import type {
|
|
18
23
|
ExtendEntityParameters,
|
|
19
24
|
ExtendEntityReturnType,
|
|
20
25
|
} from "../../actions/wallet/extendEntity"
|
|
21
26
|
import { extendEntity } from "../../actions/wallet/extendEntity"
|
|
22
|
-
import type {
|
|
23
|
-
MutateEntitiesParameters,
|
|
24
|
-
MutateEntitiesReturnType,
|
|
25
|
-
} from "../../actions/wallet/mutateEntities"
|
|
26
|
-
import { mutateEntities } from "../../actions/wallet/mutateEntities"
|
|
27
27
|
import type { PatchEntityParameters, PatchEntityReturnType } from "../../actions/wallet/patchEntity"
|
|
28
28
|
import { patchEntity } from "../../actions/wallet/patchEntity"
|
|
29
29
|
import type { TxParams } from "../../types"
|
|
@@ -50,12 +50,12 @@ export type WalletArkivActions<
|
|
|
50
50
|
/**
|
|
51
51
|
* Creates a new entity.
|
|
52
52
|
*
|
|
53
|
-
* -
|
|
54
|
-
* - JSON-RPC Methods: [`eth_sendRawTransaction`](https://docs.arkiv.network/dev/json-rpc-api/#mutateEntities)
|
|
53
|
+
* - JSON-RPC Methods: `eth_sendRawTransaction`
|
|
55
54
|
*
|
|
56
55
|
* @param data - The entity creation parameters
|
|
57
56
|
* @param txParams - Optional transaction parameters
|
|
58
|
-
* @returns The
|
|
57
|
+
* @returns The new entity's key, the transaction hash, and the block it is expected to
|
|
58
|
+
* expire at. {@link CreateEntityReturnType}
|
|
59
59
|
*
|
|
60
60
|
* @throws {InvalidExpiryError} If the expiry exceeds a protocol bound or would leave the
|
|
61
61
|
* entity dead on arrival.
|
|
@@ -67,8 +67,10 @@ export type WalletArkivActions<
|
|
|
67
67
|
* import { i32 } from "@arkiv-network/sdk/attr"
|
|
68
68
|
* import { cheesecake } from "@arkiv-network/sdk/chains"
|
|
69
69
|
* import { http } from "viem"
|
|
70
|
+
* import { privateKeyToAccount } from "viem/accounts"
|
|
70
71
|
*
|
|
71
72
|
* const client = createWalletClient({
|
|
73
|
+
* account: privateKeyToAccount("0x..."),
|
|
72
74
|
* chain: cheesecake,
|
|
73
75
|
* transport: http(),
|
|
74
76
|
* })
|
|
@@ -88,12 +90,11 @@ export type WalletArkivActions<
|
|
|
88
90
|
* Applies a patch to the entity with the given key: sets some fields, unsets others, and leaves
|
|
89
91
|
* everything it does not name alone.
|
|
90
92
|
*
|
|
91
|
-
* -
|
|
92
|
-
* - JSON-RPC Methods: [`eth_sendRawTransaction`](https://docs.arkiv.network/dev/json-rpc-api/#mutateEntities)
|
|
93
|
+
* - JSON-RPC Methods: `eth_sendRawTransaction`
|
|
93
94
|
*
|
|
94
95
|
* @param data - The entity key and the mutations to apply
|
|
95
96
|
* @param txParams - Optional transaction parameters
|
|
96
|
-
* @returns The entity key and the transaction hash
|
|
97
|
+
* @returns The patched entity's key and the transaction hash. {@link PatchEntityReturnType}
|
|
97
98
|
*
|
|
98
99
|
* @throws {EmptyPatchError} If the patch has nothing to apply.
|
|
99
100
|
* @throws {ConflictingMutationError} If a name appears in both `set` and `unset`.
|
|
@@ -105,8 +106,10 @@ export type WalletArkivActions<
|
|
|
105
106
|
* import { i32 } from "@arkiv-network/sdk/attr"
|
|
106
107
|
* import { cheesecake } from "@arkiv-network/sdk/chains"
|
|
107
108
|
* import { http } from "viem"
|
|
109
|
+
* import { privateKeyToAccount } from "viem/accounts"
|
|
108
110
|
*
|
|
109
111
|
* const client = createWalletClient({
|
|
112
|
+
* account: privateKeyToAccount("0x..."),
|
|
110
113
|
* chain: cheesecake,
|
|
111
114
|
* transport: http(),
|
|
112
115
|
* })
|
|
@@ -126,19 +129,20 @@ export type WalletArkivActions<
|
|
|
126
129
|
/**
|
|
127
130
|
* Deletes the entity with the given key.
|
|
128
131
|
*
|
|
129
|
-
* -
|
|
130
|
-
* - JSON-RPC Methods: [`eth_sendRawTransaction`](https://docs.arkiv.network/dev/json-rpc-api/#mutateEntities)
|
|
132
|
+
* - JSON-RPC Methods: `eth_sendRawTransaction`
|
|
131
133
|
*
|
|
132
134
|
* @param data - The entity deletion parameters
|
|
133
135
|
* @param txParams - Optional transaction parameters
|
|
134
|
-
* @returns The deleted entity
|
|
136
|
+
* @returns The deleted entity's key and the transaction hash. {@link DeleteEntityReturnType}
|
|
135
137
|
*
|
|
136
138
|
* @example
|
|
137
139
|
* import { createWalletClient } from "@arkiv-network/sdk"
|
|
138
140
|
* import { cheesecake } from "@arkiv-network/sdk/chains"
|
|
139
141
|
* import { http } from "viem"
|
|
142
|
+
* import { privateKeyToAccount } from "viem/accounts"
|
|
140
143
|
*
|
|
141
144
|
* const client = createWalletClient({
|
|
145
|
+
* account: privateKeyToAccount("0x..."),
|
|
142
146
|
* chain: cheesecake,
|
|
143
147
|
* transport: http(),
|
|
144
148
|
* })
|
|
@@ -157,12 +161,12 @@ export type WalletArkivActions<
|
|
|
157
161
|
* than adding to what the entity has left, and `atBlock` / `atDate` pin an absolute deadline.
|
|
158
162
|
* The engine rejects an extension that would not move the expiry later.
|
|
159
163
|
*
|
|
160
|
-
* -
|
|
161
|
-
* - JSON-RPC Methods: [`eth_sendRawTransaction`](https://docs.arkiv.network/dev/json-rpc-api/#mutateEntities)
|
|
164
|
+
* - JSON-RPC Methods: `eth_sendRawTransaction`
|
|
162
165
|
*
|
|
163
166
|
* @param data - The entity key and its new lifetime
|
|
164
167
|
* @param txParams - Optional transaction parameters
|
|
165
|
-
* @returns The entity key, transaction hash, and the block it is now expected to expire
|
|
168
|
+
* @returns The entity's key, the transaction hash, and the block it is now expected to expire
|
|
169
|
+
* at. {@link ExtendEntityReturnType}
|
|
166
170
|
*
|
|
167
171
|
* @throws {InvalidExpiryError} If the expiry is malformed, exceeds a protocol bound, or would
|
|
168
172
|
* leave the entity dead on arrival.
|
|
@@ -171,8 +175,10 @@ export type WalletArkivActions<
|
|
|
171
175
|
* import { createWalletClient, ExpirationTime } from "@arkiv-network/sdk"
|
|
172
176
|
* import { cheesecake } from "@arkiv-network/sdk/chains"
|
|
173
177
|
* import { http } from "viem"
|
|
178
|
+
* import { privateKeyToAccount } from "viem/accounts"
|
|
174
179
|
*
|
|
175
180
|
* const client = createWalletClient({
|
|
181
|
+
* account: privateKeyToAccount("0x..."),
|
|
176
182
|
* chain: cheesecake,
|
|
177
183
|
* transport: http(),
|
|
178
184
|
* })
|
|
@@ -187,14 +193,13 @@ export type WalletArkivActions<
|
|
|
187
193
|
) => Promise<ExtendEntityReturnType>
|
|
188
194
|
|
|
189
195
|
/**
|
|
190
|
-
*
|
|
196
|
+
* Hands the entity with the given key to a new owner.
|
|
191
197
|
*
|
|
192
|
-
* -
|
|
193
|
-
* - JSON-RPC Methods: [`eth_sendRawTransaction`](https://docs.arkiv.network/dev/json-rpc-api/#mutateEntities)
|
|
198
|
+
* - JSON-RPC Methods: `eth_sendRawTransaction`
|
|
194
199
|
*
|
|
195
200
|
* @param data - The ownership change parameters
|
|
196
201
|
* @param txParams - Optional transaction parameters
|
|
197
|
-
* @returns The entity
|
|
202
|
+
* @returns The entity's key and the transaction hash. {@link ChangeOwnershipReturnType}
|
|
198
203
|
*/
|
|
199
204
|
changeOwnership: (
|
|
200
205
|
data: ChangeOwnershipParameters,
|
|
@@ -202,17 +207,18 @@ export type WalletArkivActions<
|
|
|
202
207
|
) => Promise<ChangeOwnershipReturnType>
|
|
203
208
|
|
|
204
209
|
/**
|
|
205
|
-
*
|
|
210
|
+
* Applies a batch of entity operations — creates, patches, deletes, extensions and ownership
|
|
211
|
+
* transfers — in one transaction.
|
|
206
212
|
*
|
|
207
|
-
* -
|
|
208
|
-
* - JSON-RPC Methods: [`eth_sendRawTransaction`](https://docs.arkiv.network/dev/json-rpc-api/#mutateEntities)
|
|
213
|
+
* - JSON-RPC Methods: `eth_sendRawTransaction`
|
|
209
214
|
*
|
|
210
215
|
* Every operation lands in one transaction, so the whole batch applies or none of it does.
|
|
211
216
|
* At least one operation is required.
|
|
212
217
|
*
|
|
213
|
-
* @param data - The
|
|
218
|
+
* @param data - The batch parameters (creates, patches, deletes, extensions, ownershipChanges)
|
|
214
219
|
* @param txParams - Optional transaction parameters
|
|
215
|
-
* @returns The
|
|
220
|
+
* @returns The transaction hash, plus the keys touched by each kind of operation.
|
|
221
|
+
* {@link ExecuteBatchReturnType}
|
|
216
222
|
*
|
|
217
223
|
* @throws {InvalidExpiryError} If an expiry exceeds a protocol bound or would leave the entity
|
|
218
224
|
* dead on arrival.
|
|
@@ -222,12 +228,14 @@ export type WalletArkivActions<
|
|
|
222
228
|
* import { createWalletClient, ExpirationTime, jsonToPayload } from "@arkiv-network/sdk"
|
|
223
229
|
* import { cheesecake } from "@arkiv-network/sdk/chains"
|
|
224
230
|
* import { http } from "viem"
|
|
231
|
+
* import { privateKeyToAccount } from "viem/accounts"
|
|
225
232
|
*
|
|
226
233
|
* const client = createWalletClient({
|
|
234
|
+
* account: privateKeyToAccount("0x..."),
|
|
227
235
|
* chain: cheesecake,
|
|
228
236
|
* transport: http(),
|
|
229
237
|
* })
|
|
230
|
-
* const { txHash, createdEntities } = await client.
|
|
238
|
+
* const { txHash, createdEntities } = await client.executeBatch({
|
|
231
239
|
* creates: [{
|
|
232
240
|
* payload: jsonToPayload({ entityType: "testType", entityId: "testId" }),
|
|
233
241
|
* contentType: "application/json",
|
|
@@ -243,10 +251,10 @@ export type WalletArkivActions<
|
|
|
243
251
|
* ownershipChanges: [{ entityKey: keyToHandOver, newOwner }],
|
|
244
252
|
* })
|
|
245
253
|
*/
|
|
246
|
-
|
|
247
|
-
data:
|
|
254
|
+
executeBatch: (
|
|
255
|
+
data: ExecuteBatchParameters,
|
|
248
256
|
txParams?: TxParams,
|
|
249
|
-
) => Promise<
|
|
257
|
+
) => Promise<ExecuteBatchReturnType>
|
|
250
258
|
}
|
|
251
259
|
|
|
252
260
|
export function walletArkivActions<
|
|
@@ -265,7 +273,7 @@ export function walletArkivActions<
|
|
|
265
273
|
extendEntity(client, data, txParams),
|
|
266
274
|
changeOwnership: (data: ChangeOwnershipParameters, txParams?: TxParams) =>
|
|
267
275
|
changeOwnership(client, data, txParams),
|
|
268
|
-
|
|
269
|
-
|
|
276
|
+
executeBatch: (data: ExecuteBatchParameters, txParams?: TxParams) =>
|
|
277
|
+
executeBatch(client, data, txParams),
|
|
270
278
|
}
|
|
271
279
|
}
|
|
@@ -4,7 +4,7 @@ import { encodeAttributes } from "../attr/attributes"
|
|
|
4
4
|
import { dec, i32, str, u256 } from "../attr/values"
|
|
5
5
|
import { InvalidCreationFlagsError } from "./errors"
|
|
6
6
|
import { decodeCreationFlags, encodeCreationFlags } from "./flags"
|
|
7
|
-
import { MAX_SALT, predictEntityKey, randomSalt, validateSalt } from "./key"
|
|
7
|
+
import { MAX_SALT, NO_SALT, predictEntityKey, randomSalt, resolveSalt, validateSalt } from "./key"
|
|
8
8
|
import { createOperation } from "./operations"
|
|
9
9
|
import { OperationType } from "./params"
|
|
10
10
|
|
|
@@ -73,6 +73,18 @@ describe("salt", () => {
|
|
|
73
73
|
expect(() => validateSalt(MAX_SALT + 1n)).toThrow(/uint128/)
|
|
74
74
|
expect(() => validateSalt(-1n)).toThrow(/uint128/)
|
|
75
75
|
})
|
|
76
|
+
|
|
77
|
+
it("resolves NO_SALT to the zero, and passes anything else through", () => {
|
|
78
|
+
expect(resolveSalt(NO_SALT)).toBe(0n)
|
|
79
|
+
expect(resolveSalt(0n)).toBe(0n)
|
|
80
|
+
expect(resolveSalt(42n)).toBe(42n)
|
|
81
|
+
expect(() => resolveSalt(MAX_SALT + 1n)).toThrow(/uint128/)
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it("reports a salt it cannot use without choking on a symbol", () => {
|
|
85
|
+
// @ts-expect-error
|
|
86
|
+
expect(() => validateSalt(Symbol("nope"))).toThrow(/Invalid salt/)
|
|
87
|
+
})
|
|
76
88
|
})
|
|
77
89
|
|
|
78
90
|
describe("predictEntityKey", () => {
|
|
@@ -86,6 +98,13 @@ describe("predictEntityKey", () => {
|
|
|
86
98
|
).not.toBe(predictEntityKey(base))
|
|
87
99
|
})
|
|
88
100
|
|
|
101
|
+
it("derives the same key from NO_SALT as from an explicit zero", () => {
|
|
102
|
+
const base = { owner: OWNER, nonce: 3n, chainId: 1 } as const
|
|
103
|
+
expect(predictEntityKey({ ...base, salt: NO_SALT })).toBe(
|
|
104
|
+
predictEntityKey({ ...base, salt: 0n }),
|
|
105
|
+
)
|
|
106
|
+
})
|
|
107
|
+
|
|
89
108
|
it("separates chains through the domain", () => {
|
|
90
109
|
const base = { owner: OWNER, nonce: 0n, salt: 0n } as const
|
|
91
110
|
expect(predictEntityKey({ ...base, chainId: 1 })).not.toBe(
|
package/src/entity/errors.ts
CHANGED
|
@@ -16,10 +16,11 @@ export class InvalidCreationFlagsError extends Error {
|
|
|
16
16
|
|
|
17
17
|
/** A key salt was outside the `uint128` the wire carries. */
|
|
18
18
|
export class InvalidSaltError extends Error {
|
|
19
|
-
constructor(salt:
|
|
19
|
+
constructor(salt: unknown) {
|
|
20
20
|
super(
|
|
21
|
-
`Invalid salt ${salt}. A salt is a uint128, so it must be between 0 and ` +
|
|
22
|
-
`${2n ** 128n - 1n}. Omit it to get 128 random bits, or pass
|
|
21
|
+
`Invalid salt ${String(salt)}. A salt is a uint128, so it must be between 0 and ` +
|
|
22
|
+
`${2n ** 128n - 1n}. Omit it to get 128 random bits, or pass NO_SALT for a key derived ` +
|
|
23
|
+
`from the owner and nonce alone.`,
|
|
23
24
|
)
|
|
24
25
|
this.name = "InvalidSaltError"
|
|
25
26
|
}
|