@arkiv-network/sdk 0.7.0 → 0.8.0-dev.1

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.
Files changed (210) hide show
  1. package/README.md +29 -16
  2. package/dist/attr/index.cjs +34 -0
  3. package/dist/attr/index.d.cts +2 -0
  4. package/dist/attr/index.d.ts +2 -0
  5. package/dist/attr/index.js +3 -0
  6. package/dist/attr-BDZ-APg5.js +809 -0
  7. package/dist/attr-BDZ-APg5.js.map +1 -0
  8. package/dist/attr-BvxHN99W.cjs +1029 -0
  9. package/dist/chains/index.cjs +2 -3
  10. package/dist/chains/index.d.cts +39 -77
  11. package/dist/chains/index.d.cts.map +1 -1
  12. package/dist/chains/index.d.ts +22 -60
  13. package/dist/chains/index.d.ts.map +1 -1
  14. package/dist/chains/index.js +2 -2
  15. package/dist/chains-BJrZs6sG.js +57 -0
  16. package/dist/chains-BJrZs6sG.js.map +1 -0
  17. package/dist/chains-BYRTTipa.cjs +73 -0
  18. package/dist/changeOwnership-B7bEgla4.d.cts +509 -0
  19. package/dist/changeOwnership-B7bEgla4.d.cts.map +1 -0
  20. package/dist/changeOwnership-DwgtdSFc.d.ts +509 -0
  21. package/dist/changeOwnership-DwgtdSFc.d.ts.map +1 -0
  22. package/dist/entity/index.cjs +19 -0
  23. package/dist/entity/index.d.cts +4 -0
  24. package/dist/entity/index.d.ts +4 -0
  25. package/dist/entity/index.js +6 -0
  26. package/dist/entity-B0t6sN7F.cjs +71 -0
  27. package/dist/entity-BIp_df9u.js +67 -0
  28. package/dist/entity-BIp_df9u.js.map +1 -0
  29. package/dist/entity-CFhbAv0R.js +70 -0
  30. package/dist/entity-CFhbAv0R.js.map +1 -0
  31. package/dist/entity-wfBnZd91.cjs +98 -0
  32. package/dist/errors-D-eJkGVc.cjs +56 -0
  33. package/dist/errors-DGB8AgT2.js +33 -0
  34. package/dist/errors-DGB8AgT2.js.map +1 -0
  35. package/dist/expiry-BUYIXTGb.cjs +135 -0
  36. package/dist/expiry-BxOlvVWC.d.ts +79 -0
  37. package/dist/expiry-BxOlvVWC.d.ts.map +1 -0
  38. package/dist/expiry-DGRzrSan.js +95 -0
  39. package/dist/expiry-DGRzrSan.js.map +1 -0
  40. package/dist/expiry-DRV29F1r.d.cts +79 -0
  41. package/dist/expiry-DRV29F1r.d.cts.map +1 -0
  42. package/dist/flags-0Vl5rrHq.d.cts +41 -0
  43. package/dist/flags-0Vl5rrHq.d.cts.map +1 -0
  44. package/dist/flags-Ct8k0gpB.cjs +43 -0
  45. package/dist/flags-ZtlvOIIk.js +33 -0
  46. package/dist/flags-ZtlvOIIk.js.map +1 -0
  47. package/dist/flags-wmcMoAnN.d.ts +41 -0
  48. package/dist/flags-wmcMoAnN.d.ts.map +1 -0
  49. package/dist/index-Cgw1u5aY.d.cts +278 -0
  50. package/dist/index-Cgw1u5aY.d.cts.map +1 -0
  51. package/dist/index-ClgIuxJ8.d.ts +159 -0
  52. package/dist/index-ClgIuxJ8.d.ts.map +1 -0
  53. package/dist/index-D0CmtiWT.d.cts +159 -0
  54. package/dist/index-D0CmtiWT.d.cts.map +1 -0
  55. package/dist/index-D8LZt-3J.d.cts +417 -0
  56. package/dist/index-D8LZt-3J.d.cts.map +1 -0
  57. package/dist/index-DVYFaXNV.d.ts +417 -0
  58. package/dist/index-DVYFaXNV.d.ts.map +1 -0
  59. package/dist/index-VCqgn29D.d.ts +278 -0
  60. package/dist/index-VCqgn29D.d.ts.map +1 -0
  61. package/dist/index.cjs +675 -357
  62. package/dist/index.d.cts +251 -203
  63. package/dist/index.d.cts.map +1 -1
  64. package/dist/index.d.ts +251 -203
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +626 -355
  67. package/dist/index.js.map +1 -1
  68. package/dist/payload-Bnw1hrvb.cjs +83 -0
  69. package/dist/payload-CIxSn_DW.js +67 -0
  70. package/dist/payload-CIxSn_DW.js.map +1 -0
  71. package/dist/payload-Dgx3PQeK.d.ts +94 -0
  72. package/dist/payload-Dgx3PQeK.d.ts.map +1 -0
  73. package/dist/payload-P0nWyjLg.d.cts +94 -0
  74. package/dist/payload-P0nWyjLg.d.cts.map +1 -0
  75. package/dist/query/index.cjs +24 -149
  76. package/dist/query/index.d.cts +5 -3
  77. package/dist/query/index.d.ts +5 -3
  78. package/dist/query/index.js +6 -137
  79. package/dist/queryBuilder-BXDvX1K_.cjs +1123 -0
  80. package/dist/queryBuilder-CbLL4pG5.js +963 -0
  81. package/dist/queryBuilder-CbLL4pG5.js.map +1 -0
  82. package/dist/selection-BvK6yX0g.d.cts +433 -0
  83. package/dist/selection-BvK6yX0g.d.cts.map +1 -0
  84. package/dist/selection-fpmI3ADQ.d.ts +433 -0
  85. package/dist/selection-fpmI3ADQ.d.ts.map +1 -0
  86. package/dist/types/index.cjs +4 -1
  87. package/dist/types/index.d.cts +7 -2
  88. package/dist/types/index.d.ts +7 -2
  89. package/dist/types/index.js +4 -1
  90. package/dist/utils/index.cjs +4 -17
  91. package/dist/utils/index.d.cts +3 -17
  92. package/dist/utils/index.d.ts +3 -17
  93. package/dist/utils/index.js +4 -18
  94. package/package.json +26 -5
  95. package/src/actions/public/getEntity.ts +27 -43
  96. package/src/actions/public/getEntityNonce.ts +30 -0
  97. package/src/actions/public/predictEntityKeys.test.ts +143 -0
  98. package/src/actions/public/predictEntityKeys.ts +138 -0
  99. package/src/actions/public/query.ts +33 -69
  100. package/src/actions/public/watchEntityEvents.test.ts +414 -0
  101. package/src/actions/public/watchEntityEvents.ts +225 -0
  102. package/src/actions/wallet/changeOwnership.ts +8 -8
  103. package/src/actions/wallet/createEntity.ts +104 -26
  104. package/src/actions/wallet/deleteEntity.ts +2 -3
  105. package/src/actions/wallet/extendEntity.ts +39 -16
  106. package/src/actions/wallet/mutateEntities.test.ts +76 -0
  107. package/src/actions/wallet/mutateEntities.ts +29 -74
  108. package/src/actions/wallet/patchEntity.ts +90 -0
  109. package/src/attr/attributes.test.ts +120 -0
  110. package/src/attr/attributes.ts +190 -0
  111. package/src/attr/codec.test.ts +162 -0
  112. package/src/attr/codec.ts +220 -0
  113. package/src/attr/decimal.ts +86 -0
  114. package/src/attr/errors.ts +145 -0
  115. package/src/attr/index.ts +50 -0
  116. package/src/attr/names.ts +106 -0
  117. package/src/attr/types.ts +150 -0
  118. package/src/attr/values.test.ts +271 -0
  119. package/src/attr/values.ts +502 -0
  120. package/src/chains/cheesecake.ts +22 -0
  121. package/src/chains/index.ts +1 -2
  122. package/src/clients/createPublicClient.test.ts +3 -5
  123. package/src/clients/createPublicClient.ts +5 -4
  124. package/src/clients/createWalletClient.test.ts +2 -2
  125. package/src/clients/createWalletClient.ts +13 -7
  126. package/src/clients/decorators/arkivPublic.ts +160 -139
  127. package/src/clients/decorators/arkivWallet.ts +91 -95
  128. package/src/consts.ts +2 -1
  129. package/src/entity/create.test.ts +184 -0
  130. package/src/entity/errors.ts +38 -0
  131. package/src/entity/events.ts +16 -0
  132. package/src/entity/expiry.test.ts +195 -0
  133. package/src/entity/expiry.ts +181 -0
  134. package/src/entity/flags.ts +65 -0
  135. package/src/entity/index.ts +14 -0
  136. package/src/entity/key.ts +68 -0
  137. package/src/entity/operations.ts +134 -0
  138. package/src/entity/params.ts +15 -0
  139. package/src/errors.ts +33 -28
  140. package/src/index.ts +6 -0
  141. package/src/query/engine.ts +59 -134
  142. package/src/query/errors.ts +151 -0
  143. package/src/query/expression.test.ts +286 -0
  144. package/src/query/expression.ts +493 -0
  145. package/src/query/index.ts +40 -4
  146. package/src/query/injection.test.ts +151 -0
  147. package/src/query/queryBuilder.test.ts +322 -637
  148. package/src/query/queryBuilder.ts +126 -359
  149. package/src/query/queryResult.ts +54 -51
  150. package/src/query/selection.test.ts +48 -98
  151. package/src/query/selection.ts +77 -65
  152. package/src/types/entity.test.ts +44 -155
  153. package/src/types/entity.ts +62 -44
  154. package/src/types/events.ts +64 -23
  155. package/src/types/index.ts +20 -16
  156. package/src/types/rpcSchema.ts +70 -33
  157. package/src/utils/arkivTransactions.test.ts +681 -38
  158. package/src/utils/arkivTransactions.ts +249 -104
  159. package/src/utils/chains.test.ts +21 -24
  160. package/src/utils/compression.ts +1 -1
  161. package/src/utils/entities.test.ts +62 -0
  162. package/src/utils/entities.ts +111 -29
  163. package/src/utils/expirationTime.ts +114 -10
  164. package/src/utils/logger.ts +2 -2
  165. package/src/utils/payload.ts +4 -2
  166. package/src/utils/revert.test.ts +99 -0
  167. package/src/utils/revert.ts +145 -0
  168. package/dist/chains-BifaY04V.cjs +0 -108
  169. package/dist/chains-CrtkVbBh.js +0 -86
  170. package/dist/chains-CrtkVbBh.js.map +0 -1
  171. package/dist/consts-AUoL-v42.cjs +0 -18
  172. package/dist/consts-BV4PR-de.js +0 -7
  173. package/dist/consts-BV4PR-de.js.map +0 -1
  174. package/dist/entity-B6g_EPm1.d.cts +0 -382
  175. package/dist/entity-B6g_EPm1.d.cts.map +0 -1
  176. package/dist/entity-qoLMAuuk.d.ts +0 -382
  177. package/dist/entity-qoLMAuuk.d.ts.map +0 -1
  178. package/dist/index-DdspxNAA.d.ts +0 -481
  179. package/dist/index-DdspxNAA.d.ts.map +0 -1
  180. package/dist/index-Ds9dwqb5.d.cts +0 -481
  181. package/dist/index-Ds9dwqb5.d.cts.map +0 -1
  182. package/dist/payload-B2kFJyah.d.ts +0 -6
  183. package/dist/payload-B2kFJyah.d.ts.map +0 -1
  184. package/dist/payload-CJN8fTvX.d.cts +0 -6
  185. package/dist/payload-CJN8fTvX.d.cts.map +0 -1
  186. package/dist/payload-Claf2jUO.js +0 -13
  187. package/dist/payload-Claf2jUO.js.map +0 -1
  188. package/dist/payload-DpA5PA-w.cjs +0 -23
  189. package/dist/query/index.js.map +0 -1
  190. package/dist/queryBuilder-D2uwP9jI.js +0 -704
  191. package/dist/queryBuilder-D2uwP9jI.js.map +0 -1
  192. package/dist/queryBuilder-UW2MCaX4.cjs +0 -792
  193. package/dist/utils/index.d.cts.map +0 -1
  194. package/dist/utils/index.d.ts.map +0 -1
  195. package/dist/utils/index.js.map +0 -1
  196. package/src/actions/public/buildQuery.ts +0 -10
  197. package/src/actions/public/subscribeEntityEvents.ts +0 -119
  198. package/src/actions/wallet/updateEntity.ts +0 -60
  199. package/src/chains/braga.ts +0 -26
  200. package/src/chains/kaolin.ts +0 -29
  201. package/src/query/engine.test.ts +0 -526
  202. package/src/query/predicate.test.ts +0 -461
  203. package/src/query/predicate.ts +0 -144
  204. package/src/query/queryResult.test.ts +0 -270
  205. package/src/query/selectQueryBuilder.test.ts +0 -210
  206. package/src/types/attributes.ts +0 -16
  207. package/src/utils/validation.test.ts +0 -60
  208. package/src/utils/validation.ts +0 -32
  209. /package/dist/{types-H-TSmRpm.js → types-Bx1EKe0v.js} +0 -0
  210. /package/dist/{types-o3zWarRp.cjs → types-CKPddlfS.cjs} +0 -0
@@ -1,179 +1,68 @@
1
- import { describe, expect, test } from "bun:test"
1
+ import { describe, expect, it } from "bun:test"
2
+ import { i32, str } from "../attr"
2
3
  import { Entity } from "./entity"
3
4
 
4
- const KEY = "0xabc" as const
5
+ const KEY = `0x${"ab".repeat(32)}` as const
5
6
 
6
- describe("Entity.toText()", () => {
7
- test("throws when payload is undefined", () => {
8
- const entity = new Entity(
9
- KEY,
10
- undefined,
11
- undefined,
12
- undefined,
13
- undefined,
14
- undefined,
15
- undefined,
16
- undefined,
17
- undefined,
18
- undefined,
19
- [],
20
- )
21
- expect(() => entity.toText()).toThrow(
22
- "Entity has no payload – it was probably queried without withPayload(true) via QueryBuilder",
23
- )
24
- })
7
+ function withPayload(text: string): Entity {
8
+ return new Entity({ key: KEY, payload: new TextEncoder().encode(text) })
9
+ }
25
10
 
26
- test("returns string when payload is valid bytes", () => {
27
- const payload = new TextEncoder().encode("hello world")
28
- const entity = new Entity(
29
- KEY,
30
- undefined,
31
- undefined,
32
- undefined,
33
- undefined,
34
- undefined,
35
- undefined,
36
- undefined,
37
- undefined,
38
- payload,
39
- [],
40
- )
41
- expect(entity.toText()).toBe("hello world")
11
+ describe("Entity", () => {
12
+ it("carries only the fields it was built with", () => {
13
+ const entity = new Entity({
14
+ key: KEY,
15
+ expiresAt: 1_297_000n,
16
+ attributes: { level: i32(10), name: str("Bob") },
17
+ })
18
+ expect(entity.key).toBe(KEY)
19
+ expect(entity.expiresAt).toBe(1_297_000n)
20
+ expect(entity.attributes?.level.value).toBe(10)
21
+ // Not selected is not the same as empty: nothing here stands in for data that was not asked for.
22
+ expect(entity.owner).toBeUndefined()
23
+ expect(entity.payload).toBeUndefined()
24
+ expect(entity.attributeSchema).toBeUndefined()
42
25
  })
43
26
 
44
- test("returns empty string when payload is empty", () => {
45
- const entity = new Entity(
46
- KEY,
47
- undefined,
48
- undefined,
49
- undefined,
50
- undefined,
51
- undefined,
52
- undefined,
53
- undefined,
54
- undefined,
55
- new Uint8Array([]),
56
- [],
57
- )
58
- expect(entity.toText()).toBe("")
27
+ it("defaults to carrying nothing at all", () => {
28
+ expect(new Entity().key).toBeUndefined()
59
29
  })
60
30
  })
61
31
 
62
- describe("Entity.toJson()", () => {
63
- test("throws when payload is undefined", () => {
64
- const entity = new Entity(
65
- KEY,
66
- undefined,
67
- undefined,
68
- undefined,
69
- undefined,
70
- undefined,
71
- undefined,
72
- undefined,
73
- undefined,
74
- undefined,
75
- [],
76
- )
77
- expect(() => entity.toJson()).toThrow(
78
- "Entity has no payload – it was probably queried without withPayload(true) via QueryBuilder",
79
- )
32
+ describe("toText", () => {
33
+ it("decodes the payload as UTF-8", () => {
34
+ expect(withPayload("hello world").toText()).toBe("hello world")
35
+ expect(withPayload("").toText()).toBe("")
36
+ })
37
+
38
+ it("says how to ask for the payload when it was not selected", () => {
39
+ expect(() => new Entity({ key: KEY }).toText()).toThrow(/select\(\{ payload: true \}\)/)
80
40
  })
41
+ })
81
42
 
82
- test("throws when payload is empty", () => {
83
- const entity = new Entity(
84
- KEY,
85
- undefined,
86
- undefined,
87
- undefined,
88
- undefined,
89
- undefined,
90
- undefined,
91
- undefined,
92
- undefined,
93
- new Uint8Array([]),
94
- [],
95
- )
96
- expect(() => entity.toJson()).toThrow("Entity has empty payload, cannot parse as JSON")
43
+ describe("toJson", () => {
44
+ it("parses objects and arrays", () => {
45
+ expect(withPayload('{"a":1,"b":[2,3]}').toJson()).toEqual({ a: 1, b: [2, 3] })
46
+ expect(withPayload("[1,2,3]").toJson()).toEqual([1, 2, 3])
97
47
  })
98
48
 
99
- test("throws when payload is invalid JSON", () => {
100
- const payload = new TextEncoder().encode("not valid json {")
101
- const entity = new Entity(
102
- KEY,
103
- undefined,
104
- undefined,
105
- undefined,
106
- undefined,
107
- undefined,
108
- undefined,
109
- undefined,
110
- undefined,
111
- payload,
112
- [],
113
- )
114
- expect(() => entity.toJson()).toThrow("Failed to parse entity payload as JSON")
49
+ it("throws on an empty payload rather than returning undefined", () => {
50
+ expect(() => withPayload("").toJson()).toThrow(/empty payload/)
115
51
  })
116
52
 
117
- test("preserves original error as cause when JSON parsing fails", () => {
118
- const payload = new TextEncoder().encode("not valid json {")
119
- const entity = new Entity(
120
- KEY,
121
- undefined,
122
- undefined,
123
- undefined,
124
- undefined,
125
- undefined,
126
- undefined,
127
- undefined,
128
- undefined,
129
- payload,
130
- [],
131
- )
53
+ it("keeps the parse failure as the cause", () => {
132
54
  let caught: unknown
133
55
  try {
134
- entity.toJson()
135
- } catch (e) {
136
- caught = e
56
+ withPayload("not json").toJson()
57
+ } catch (error) {
58
+ caught = error
137
59
  }
138
60
  expect(caught).toBeInstanceOf(Error)
61
+ expect((caught as Error).message).toMatch(/Failed to parse entity payload as JSON/)
139
62
  expect((caught as Error).cause).toBeInstanceOf(Error)
140
63
  })
141
64
 
142
- test("returns parsed object for valid JSON payload", () => {
143
- const data = { foo: "bar", count: 42 }
144
- const payload = new TextEncoder().encode(JSON.stringify(data))
145
- const entity = new Entity(
146
- KEY,
147
- undefined,
148
- undefined,
149
- undefined,
150
- undefined,
151
- undefined,
152
- undefined,
153
- undefined,
154
- undefined,
155
- payload,
156
- [],
157
- )
158
- expect(entity.toJson()).toEqual(data)
159
- })
160
-
161
- test("returns parsed array for valid JSON array payload", () => {
162
- const data = [1, 2, 3]
163
- const payload = new TextEncoder().encode(JSON.stringify(data))
164
- const entity = new Entity(
165
- KEY,
166
- undefined,
167
- undefined,
168
- undefined,
169
- undefined,
170
- undefined,
171
- undefined,
172
- undefined,
173
- undefined,
174
- payload,
175
- [],
176
- )
177
- expect(entity.toJson()).toEqual(data)
65
+ it("reports the missing payload, not a JSON error", () => {
66
+ expect(() => new Entity({ key: KEY }).toJson()).toThrow(/did not select it/)
178
67
  })
179
68
  })
@@ -1,56 +1,74 @@
1
1
  import { bytesToString, type Hex } from "viem"
2
- import type { MimeType } from "../types"
3
- import type { Attribute } from "./attributes"
2
+ import type { AttributeSchema, Attributes } from "../attr"
3
+ import type { ResolvedCreationFlags } from "../entity/flags"
4
4
 
5
- export class Entity {
6
- key: Hex
7
- contentType: MimeType | undefined
5
+ /**
6
+ * The fields an {@link Entity} can carry. Every one is optional: a query returns exactly the parts
7
+ * it selected, and `undefined` means "not asked for" rather than "empty".
8
+ */
9
+ export type EntityFields = {
10
+ key?: Hex | undefined
11
+ owner?: Hex | undefined
12
+ creator?: Hex | undefined
13
+ /** Block the entity was created at. */
14
+ createdAt?: bigint | undefined
15
+ /** Block the entity was last patched at. */
16
+ updatedAt?: bigint | undefined
17
+ /** Block the entity expires at. */
18
+ expiresAt?: bigint | undefined
19
+ /** The immutable properties the entity was created with. */
20
+ creationFlags?: ResolvedCreationFlags | undefined
21
+ contentType?: string | undefined
22
+ payload?: Uint8Array | undefined
23
+ /** Attribute names and types, with no values. */
24
+ attributeSchema?: AttributeSchema | undefined
25
+ /** Attribute names, types and values. */
26
+ attributes?: Attributes | undefined
27
+ }
28
+
29
+ /**
30
+ * An entity as it comes back from a query.
31
+ *
32
+ * Which fields are populated is decided by the query's selection — `select({ key: true })` gives
33
+ * back an entity carrying only its key. The static type of a `select()` result is narrowed to
34
+ * exactly the selected fields, so in typed code the `undefined`s here are not reachable.
35
+ */
36
+ export class Entity implements EntityFields {
37
+ key: Hex | undefined
8
38
  owner: Hex | undefined
9
39
  creator: Hex | undefined
10
- expiresAtBlock: bigint | undefined
11
- createdAtBlock: bigint | undefined
12
- lastModifiedAtBlock: bigint | undefined
13
- transactionIndexInBlock: bigint | undefined
14
- operationIndexInTransaction: bigint | undefined
40
+ createdAt: bigint | undefined
41
+ updatedAt: bigint | undefined
42
+ expiresAt: bigint | undefined
43
+ creationFlags: ResolvedCreationFlags | undefined
44
+ contentType: string | undefined
15
45
  payload: Uint8Array | undefined
16
- attributes: Attribute[]
46
+ attributeSchema: AttributeSchema | undefined
47
+ attributes: Attributes | undefined
17
48
 
18
- constructor(
19
- key: Hex,
20
- contentType: MimeType | undefined = undefined,
21
- owner: Hex | undefined = undefined,
22
- creator: Hex | undefined = undefined,
23
- expiresAtBlock: bigint | undefined = undefined,
24
- createdAtBlock: bigint | undefined = undefined,
25
- lastModifiedAtBlock: bigint | undefined = undefined,
26
- transactionIndexInBlock: bigint | undefined = undefined,
27
- operationIndexInTransaction: bigint | undefined = undefined,
28
- payload: Uint8Array | undefined = undefined,
29
- attributes: Attribute[],
30
- ) {
31
- this.key = key
32
- this.owner = owner
33
- this.creator = creator
34
- this.expiresAtBlock = expiresAtBlock
35
- this.createdAtBlock = createdAtBlock
36
- this.lastModifiedAtBlock = lastModifiedAtBlock
37
- this.transactionIndexInBlock = transactionIndexInBlock
38
- this.operationIndexInTransaction = operationIndexInTransaction
39
- this.payload = payload
40
- this.attributes = attributes
41
- this.contentType = contentType
49
+ constructor(fields: EntityFields = {}) {
50
+ this.key = fields.key
51
+ this.owner = fields.owner
52
+ this.creator = fields.creator
53
+ this.createdAt = fields.createdAt
54
+ this.updatedAt = fields.updatedAt
55
+ this.expiresAt = fields.expiresAt
56
+ this.creationFlags = fields.creationFlags
57
+ this.contentType = fields.contentType
58
+ this.payload = fields.payload
59
+ this.attributeSchema = fields.attributeSchema
60
+ this.attributes = fields.attributes
42
61
  }
43
62
 
44
63
  /**
45
- * Converts the entity payload from bytes to a string and returns it.
46
- * Throws an error if the payload is undefined, which may occur if the entity was not queried with the withPayload option.
47
- * Throws an error if the conversion from bytes to string fails.
48
- * @returns The entity payload as a string.
64
+ * The payload decoded as UTF-8 text.
65
+ *
66
+ * @throws If the payload was not selected, or is not valid UTF-8.
49
67
  */
50
68
  toText(): string {
51
69
  if (this.payload === undefined) {
52
70
  throw new Error(
53
- "Entity has no payload – it was probably queried without withPayload(true) via QueryBuilder",
71
+ "Entity has no payload — the query did not select it. Use select({ payload: true }).",
54
72
  )
55
73
  }
56
74
  try {
@@ -64,11 +82,11 @@ export class Entity {
64
82
  }
65
83
 
66
84
  /**
67
- * Parses the entity payload as JSON and returns the resulting object.
68
- * Throws an error if the payload is undefined, which may occur if the entity was not queried with the withPayload option.
69
- * Throws an error if the payload is empty or cannot be parsed as JSON.
70
- * @returns The parsed JSON object from the entity payload.
85
+ * The payload parsed as JSON.
86
+ *
87
+ * @throws If the payload was not selected, is empty, or is not valid JSON.
71
88
  */
89
+ // biome-ignore lint/suspicious/noExplicitAny: JSON.parse returns whatever the payload holds.
72
90
  toJson(): any {
73
91
  const text = this.toText()
74
92
  if (!text) {
@@ -1,40 +1,81 @@
1
- import type { Hex } from "viem"
1
+ import type { Address, Hex } from "viem"
2
+ import type { ResolvedCreationFlags } from "../entity/flags"
2
3
 
3
- export type OnEntityCreatedEvent = {
4
- entityKey: Hex
5
- owner: Hex
6
- expirationBlock: number
7
- cost: bigint
4
+ /**
5
+ * Where an event sits in the chain — carried by every on-chain entity event.
6
+ *
7
+ * Operations apply in batch order and emit one event each, so `blockNumber` and `logIndex` together
8
+ * are the order the operations were applied in. A replica that replays them in that order sees
9
+ * exactly what the engine did.
10
+ */
11
+ export type EntityEventContext = {
12
+ /** The block the operation was applied in. */
13
+ blockNumber: bigint
14
+ /** The transaction the operation was part of. */
15
+ transactionHash: Hex
16
+ /** The event's position within its block. */
17
+ logIndex: number
8
18
  }
9
19
 
10
- export type OnEntityUpdatedEvent = {
20
+ /** An entity was created. */
21
+ export type EntityCreatedEvent = EntityEventContext & {
22
+ type: "EntityCreated"
11
23
  entityKey: Hex
12
- owner: Hex
13
- oldExpirationBlock: number
14
- newExpirationBlock: number
15
- cost: bigint
24
+ owner: Address
25
+ /** The block the entity is set to expire at. */
26
+ expiresAt: bigint
27
+ /**
28
+ * The immutable properties the entity was created with, decoded from its `creationFlags` byte.
29
+ */
30
+ creationFlags: ResolvedCreationFlags
16
31
  }
17
32
 
18
- export type OnEntityDeletedEvent = {
33
+ /**
34
+ * An entity's attributes or payload changed.
35
+ *
36
+ * The event says *that* it changed, not what to — read the entity to see the new state.
37
+ */
38
+ export type EntityPatchedEvent = EntityEventContext & {
39
+ type: "EntityPatched"
19
40
  entityKey: Hex
20
- owner: Hex
41
+ owner: Address
21
42
  }
22
43
 
23
- export type OnEntityExpiredEvent = {
44
+ /** An entity's expiry moved further out. */
45
+ export type ExpiryExtendedEvent = EntityEventContext & {
46
+ type: "ExpiryExtended"
24
47
  entityKey: Hex
25
- owner: Hex
48
+ /**
49
+ * The entity's owner — **not** whoever extended it. An entity created with
50
+ * `permissionlessExtension` can be extended by anyone, and the event does not say by whom; read
51
+ * the transaction's sender if you need that.
52
+ */
53
+ owner: Address
54
+ /** The block the entity is now set to expire at. */
55
+ expiresAt: bigint
26
56
  }
27
57
 
28
- export type OnEntityExpiresInExtendedEvent = {
58
+ /** An entity changed hands. */
59
+ export type OwnershipTransferredEvent = EntityEventContext & {
60
+ type: "OwnershipTransferred"
29
61
  entityKey: Hex
30
- owner: Hex
31
- oldExpirationBlock: number
32
- newExpirationBlock: number
33
- cost: bigint
62
+ previousOwner: Address
63
+ newOwner: Address
34
64
  }
35
65
 
36
- export type OnEntityOwnerChangedEvent = {
66
+ /** An entity was deleted by its owner, before its expiry. */
67
+ export type EntityDeletedEvent = EntityEventContext & {
68
+ type: "EntityDeleted"
37
69
  entityKey: Hex
38
- oldOwner: Hex
39
- newOwner: Hex
70
+ owner: Address
40
71
  }
72
+
73
+ /**
74
+ * Every event the engine emits, discriminated by `type`.
75
+ */
76
+ export type EntityEvent =
77
+ | EntityCreatedEvent
78
+ | EntityPatchedEvent
79
+ | ExpiryExtendedEvent
80
+ | OwnershipTransferredEvent
81
+ | EntityDeletedEvent
@@ -1,10 +1,11 @@
1
1
  export type { GetBlockTimingReturnType } from "../actions/public/getBlockTiming"
2
2
  export type {
3
- QueryOptions,
4
- QueryOptionsIncludeData,
5
- QueryOptionsOrderBy,
6
- QueryReturnType,
7
- } from "../actions/public/query"
3
+ PredictEntityKeysParameters,
4
+ PredictEntityKeysReturnType,
5
+ PredictedEntityKey,
6
+ } from "../actions/public/predictEntityKeys"
7
+ export type { QueryOptions, QueryReturnType } from "../actions/public/query"
8
+ export type { WatchEntityEventsParameters } from "../actions/public/watchEntityEvents"
8
9
  export type {
9
10
  ChangeOwnershipParameters,
10
11
  ChangeOwnershipReturnType,
@@ -16,23 +17,26 @@ export type {
16
17
  MutateEntitiesParameters,
17
18
  MutateEntitiesReturnType,
18
19
  } from "../actions/wallet/mutateEntities"
19
- export type { UpdateEntityParameters, UpdateEntityReturnType } from "../actions/wallet/updateEntity"
20
- export type { Attribute } from "./attributes"
21
- export type { Entity } from "./entity"
20
+ export type { PatchEntityParameters, PatchEntityReturnType } from "../actions/wallet/patchEntity"
21
+ export type { EntityFields } from "./entity"
22
+ export { Entity } from "./entity"
22
23
  export type {
23
- OnEntityCreatedEvent,
24
- OnEntityDeletedEvent,
25
- OnEntityExpiredEvent,
26
- OnEntityExpiresInExtendedEvent,
27
- OnEntityOwnerChangedEvent,
28
- OnEntityUpdatedEvent,
24
+ EntityCreatedEvent,
25
+ EntityDeletedEvent,
26
+ EntityEvent,
27
+ EntityEventContext,
28
+ EntityPatchedEvent,
29
+ ExpiryExtendedEvent,
30
+ OwnershipTransferredEvent,
29
31
  } from "./events"
30
32
  export type { MimeType } from "./mimeTypes"
31
33
  export type {
32
34
  ArkivRpcSchema,
35
+ RpcAttribute,
36
+ RpcAttributeSchemaEntry,
37
+ RpcCreationFlags,
33
38
  RpcEntity,
34
- RpcIncludeData,
35
- RpcOrderByAttribute,
36
39
  RpcQueryOptions,
40
+ RpcSelect,
37
41
  } from "./rpcSchema"
38
42
  export type { TxParams } from "./txParams"
@@ -1,47 +1,83 @@
1
1
  import type { Hex, PublicRpcSchema } from "viem"
2
- import type { MimeType } from "./mimeTypes"
3
2
 
4
- export type RpcEntity = {
5
- key: Hex
6
- contentType: MimeType
7
- value: string
8
- expiresAt: Hex
9
- createdAtBlock: Hex
10
- lastModifiedAtBlock: Hex
11
- transactionIndexInBlock: Hex
12
- operationIndexInTransaction: Hex
13
- owner: Hex
14
- creator: Hex
15
- stringAttributes?: [{ key: string; value: string }]
16
- numericAttributes?: [{ key: string; value: Hex }]
3
+ /**
4
+ * An attribute as the node renders it: the name, the type **tag** (not the wire typeId), and the
5
+ * value in the JSON encoding that type prescribes — a JSON number for `i32`, a `0x` QUANTITY for
6
+ * `u64` and `u256`, a decimal string for `dec`, `0x` DATA for the byte-shaped types, and a string for
7
+ * `str`.
8
+ *
9
+ * The encoding follows the *declared type*, never the magnitude, so a decoder dispatches on `type`
10
+ * and never has to guess from the shape of the value.
11
+ */
12
+ export type RpcAttribute = {
13
+ name: string
14
+ type: string
15
+ value: unknown
17
16
  }
18
17
 
19
- export type RpcOrderByAttribute = {
18
+ /** An entry of the `attributeSchema` projection — a name and its type, with no value. */
19
+ export type RpcAttributeSchemaEntry = {
20
20
  name: string
21
- type: "string" | "numeric"
22
- desc: boolean
21
+ type: string
23
22
  }
24
23
 
25
- export type RpcQueryOptions = {
26
- atBlock?: Hex
27
- includeData?: RpcIncludeData
28
- orderBy?: RpcOrderByAttribute[]
29
- resultsPerPage?: Hex
30
- cursor?: string
24
+ /**
25
+ * The `creationFlags` projection.
26
+ */
27
+ export type RpcCreationFlags = {
28
+ readonly?: boolean
29
+ permissionlessExtension?: boolean
30
+ raw: number
31
31
  }
32
32
 
33
- export type RpcIncludeData = {
33
+ /**
34
+ * An entity as `arkiv_query` returns it. Every field is present only if it was selected, so all of
35
+ * them are optional here — {@link RpcSelect} is what decides which arrive.
36
+ */
37
+ export type RpcEntity = {
38
+ key?: Hex
39
+ owner?: Hex
40
+ creator?: Hex
41
+ createdAt?: Hex
42
+ updatedAt?: Hex
43
+ expiresAt?: Hex
44
+ creationFlags?: RpcCreationFlags | number
45
+ contentType?: string
46
+ payload?: Hex
47
+ attributeSchema?: RpcAttributeSchemaEntry[]
48
+ attributes?: RpcAttribute[]
49
+ }
50
+
51
+ /**
52
+ * The `select` projection: flat, per-field booleans. Everything except `key` defaults to **off**,
53
+ * so a query asks for exactly what it needs and nothing more.
54
+ *
55
+ * `attributes` is the one field with a third form: `true` for every attribute, or a map of names
56
+ * for a subset.
57
+ */
58
+ export type RpcSelect = {
34
59
  key?: boolean
35
- attributes?: boolean
36
- payload?: boolean
37
- contentType?: boolean
38
- expiration?: boolean
39
60
  owner?: boolean
40
61
  creator?: boolean
41
- createdAtBlock?: boolean
42
- lastModifiedAtBlock?: boolean
43
- transactionIndexInBlock?: boolean
44
- operationIndexInTransaction?: boolean
62
+ createdAt?: boolean
63
+ updatedAt?: boolean
64
+ expiresAt?: boolean
65
+ creationFlags?: boolean
66
+ contentType?: boolean
67
+ payload?: boolean
68
+ attributeSchema?: boolean
69
+ attributes?: boolean | Record<string, boolean>
70
+ }
71
+
72
+ export type RpcQueryOptions = {
73
+ /** Block height to read at, as a hex quantity. Defaults to the head, and must be within the node's retained range. */
74
+ atBlock?: Hex
75
+ /** What to return. Defaults to `{ key: true }`. */
76
+ select?: RpcSelect
77
+ /** Page size, as a hex quantity. Node maximum is 200. */
78
+ limit?: Hex
79
+ /** Opaque cursor from a previous response; bound to that query, block and selection. */
80
+ cursor?: string
45
81
  }
46
82
 
47
83
  export type ArkivRpcSchema = [
@@ -51,7 +87,8 @@ export type ArkivRpcSchema = [
51
87
  ReturnType: {
52
88
  data: RpcEntity[]
53
89
  blockNumber: Hex
54
- cursor: string
90
+ /** Omitted when no pages remain. */
91
+ cursor?: string
55
92
  }
56
93
  },
57
94
  {