@arkiv-network/sdk 0.1.1-dev.0 → 0.1.3-dev.0

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 (58) hide show
  1. package/README.md +22 -10
  2. package/dist/chains/index.d.ts +25 -25
  3. package/dist/chains/index.d.ts.map +1 -1
  4. package/dist/index.cjs +30 -9
  5. package/dist/index.js +30 -16
  6. package/dist/index.js.map +1 -1
  7. package/dist/utils/index.d.ts.map +1 -1
  8. package/package.json +22 -8
  9. package/src/accounts/index.ts +1 -0
  10. package/src/actions/public/buildQuery.ts +6 -0
  11. package/src/actions/public/getBlockTiming.ts +20 -0
  12. package/src/actions/public/getEntity.ts +18 -0
  13. package/src/actions/public/getEntityCount.ts +10 -0
  14. package/src/actions/public/query.ts +13 -0
  15. package/src/actions/public/subscribeEntityEvents.ts +105 -0
  16. package/src/actions/wallet/changeOwnership.ts +40 -0
  17. package/src/actions/wallet/createEntity.ts +45 -0
  18. package/src/actions/wallet/deleteEntity.ts +39 -0
  19. package/src/actions/wallet/extendEntity.ts +41 -0
  20. package/src/actions/wallet/mutateEntities.ts +100 -0
  21. package/src/actions/wallet/updateEntity.ts +47 -0
  22. package/src/chains/index.ts +3 -0
  23. package/src/chains/kaolin.ts +26 -0
  24. package/src/chains/localhost.ts +14 -0
  25. package/src/chains/marketplace.ts +26 -0
  26. package/src/clients/baseClient.ts +9 -0
  27. package/src/clients/createPublicClient.test.ts +22 -0
  28. package/src/clients/createPublicClient.ts +65 -0
  29. package/src/clients/createWalletClient.test.ts +23 -0
  30. package/src/clients/createWalletClient.ts +70 -0
  31. package/src/clients/decorators/arkivPublic.ts +203 -0
  32. package/src/clients/decorators/arkivWallet.ts +250 -0
  33. package/src/consts.ts +2 -0
  34. package/src/index.ts +21 -0
  35. package/src/query/engine.test.ts +288 -0
  36. package/src/query/engine.ts +112 -0
  37. package/src/query/errors.ts +23 -0
  38. package/src/query/index.ts +4 -0
  39. package/src/query/predicate.test.ts +418 -0
  40. package/src/query/predicate.ts +140 -0
  41. package/src/query/queryBuilder.test.ts +537 -0
  42. package/src/query/queryBuilder.ts +209 -0
  43. package/src/query/queryResult.test.ts +270 -0
  44. package/src/query/queryResult.ts +61 -0
  45. package/src/types/attributes.ts +4 -0
  46. package/src/types/entity.ts +36 -0
  47. package/src/types/events.ts +34 -0
  48. package/src/types/index.ts +4 -0
  49. package/src/types/mimeTypes.ts +27 -0
  50. package/src/types/rpcSchema.ts +61 -0
  51. package/src/types/txParams.ts +15 -0
  52. package/src/utils/arkivTransactions.ts +100 -0
  53. package/src/utils/compression.test.ts +32 -0
  54. package/src/utils/compression.ts +99 -0
  55. package/src/utils/entities.ts +23 -0
  56. package/src/utils/expirationTime.ts +13 -0
  57. package/src/utils/index.ts +3 -0
  58. package/src/utils/payload.ts +9 -0
@@ -0,0 +1,288 @@
1
+ import { describe, expect, it, jest } from "bun:test"
2
+ import type { ArkivClient } from "../clients/baseClient"
3
+ import { processQuery } from "./engine"
4
+ import type { Predicate } from "./predicate"
5
+
6
+ describe("processQuery tests", () => {
7
+ const client = {
8
+ request: jest.fn(),
9
+ } as unknown as ArkivClient
10
+
11
+ it("should process single predicate", async () => {
12
+ const predicates = [{ type: "eq" as const, key: "key", value: "value" }]
13
+ await processQuery(client, {
14
+ predicates,
15
+ limit: undefined,
16
+ cursor: undefined,
17
+ ownedBy: undefined,
18
+ validAtBlock: undefined,
19
+ withAttributes: undefined,
20
+ withMetadata: undefined,
21
+ withPayload: undefined,
22
+ })
23
+
24
+ expect(client.request).lastCalledWith({
25
+ method: "arkiv_query",
26
+ params: [
27
+ `key = "value"`,
28
+ {
29
+ includeData: {
30
+ key: true,
31
+ attributes: false,
32
+ contentType: false,
33
+ payload: false,
34
+ expiration: false,
35
+ owner: false,
36
+ },
37
+ },
38
+ ],
39
+ })
40
+ })
41
+
42
+ it("should process all simple predicates - flat", async () => {
43
+ const predicates = [
44
+ { type: "eq" as const, key: "key", value: "value" },
45
+ { type: "gt" as const, key: "key2", value: 1 },
46
+ { type: "gte" as const, key: "key3", value: 2 },
47
+ { type: "lt" as const, key: "key4", value: 3 },
48
+ { type: "lte" as const, key: "key5", value: 4 },
49
+ { type: "neq" as const, key: "key6", value: "value6" },
50
+ ]
51
+ await processQuery(client, {
52
+ predicates,
53
+ limit: undefined,
54
+ cursor: undefined,
55
+ ownedBy: undefined,
56
+ validAtBlock: undefined,
57
+ withAttributes: undefined,
58
+ withMetadata: undefined,
59
+ })
60
+
61
+ expect(client.request).lastCalledWith({
62
+ method: "arkiv_query",
63
+ params: [
64
+ `key = "value" && key2 > 1 && key3 >= 2 && key4 < 3 && key5 <= 4 && key6 != "value6"`,
65
+ {
66
+ includeData: {
67
+ key: true,
68
+ attributes: false,
69
+ contentType: false,
70
+ payload: false,
71
+ expiration: false,
72
+ owner: false,
73
+ },
74
+ },
75
+ ],
76
+ })
77
+ })
78
+
79
+ it("should process multiple predicates - nested with or", async () => {
80
+ const predicates = [
81
+ { type: "eq" as const, key: "key", value: "value" },
82
+ {
83
+ type: "or" as const,
84
+ predicates: [
85
+ { type: "eq" as const, key: "key2", value: "value2" },
86
+ { type: "eq" as const, key: "key3", value: "value3" },
87
+ ],
88
+ },
89
+ ]
90
+ await processQuery(client, {
91
+ predicates,
92
+ limit: undefined,
93
+ cursor: undefined,
94
+ ownedBy: undefined,
95
+ validAtBlock: undefined,
96
+ withAttributes: undefined,
97
+ withMetadata: undefined,
98
+ })
99
+
100
+ expect(client.request).lastCalledWith({
101
+ method: "arkiv_query",
102
+ params: [
103
+ `key = "value" && (key2 = "value2" || key3 = "value3")`,
104
+ {
105
+ includeData: {
106
+ key: true,
107
+ attributes: false,
108
+ contentType: false,
109
+ payload: false,
110
+ expiration: false,
111
+ owner: false,
112
+ },
113
+ },
114
+ ],
115
+ })
116
+ })
117
+
118
+ it("should process multiple predicates - nested with and", async () => {
119
+ const predicates = [
120
+ { type: "eq" as const, key: "key", value: "value" },
121
+ {
122
+ type: "and" as const,
123
+ predicates: [
124
+ { type: "eq" as const, key: "key2", value: "value2" },
125
+ { type: "eq" as const, key: "key3", value: "value3" },
126
+ ],
127
+ },
128
+ ]
129
+ await processQuery(client, {
130
+ predicates,
131
+ limit: undefined,
132
+ cursor: undefined,
133
+ ownedBy: undefined,
134
+ validAtBlock: undefined,
135
+ withAttributes: undefined,
136
+ withMetadata: undefined,
137
+ })
138
+
139
+ expect(client.request).lastCalledWith({
140
+ method: "arkiv_query",
141
+ params: [
142
+ `key = "value" && (key2 = "value2" && key3 = "value3")`,
143
+ {
144
+ includeData: {
145
+ key: true,
146
+ attributes: false,
147
+ contentType: false,
148
+ payload: false,
149
+ expiration: false,
150
+ owner: false,
151
+ },
152
+ },
153
+ ],
154
+ })
155
+ })
156
+
157
+ it("should process multiple predicates - nested with and and or", async () => {
158
+ const predicates = [
159
+ { type: "eq" as const, key: "key", value: "value" },
160
+ {
161
+ type: "and" as const,
162
+ predicates: [
163
+ { type: "eq" as const, key: "key2", value: "value2" },
164
+ {
165
+ type: "or" as const,
166
+ predicates: [
167
+ { type: "eq" as const, key: "key3", value: "value3" },
168
+ { type: "eq" as const, key: "key4", value: "value4" },
169
+ ],
170
+ },
171
+ ],
172
+ },
173
+ ]
174
+ await processQuery(client, {
175
+ predicates,
176
+ limit: undefined,
177
+ cursor: undefined,
178
+ ownedBy: undefined,
179
+ validAtBlock: undefined,
180
+ withAttributes: undefined,
181
+ withMetadata: undefined,
182
+ })
183
+
184
+ expect(client.request).lastCalledWith({
185
+ method: "arkiv_query",
186
+ params: [
187
+ `key = "value" && (key2 = "value2" && (key3 = "value3" || key4 = "value4"))`,
188
+ {
189
+ includeData: {
190
+ key: true,
191
+ attributes: false,
192
+ contentType: false,
193
+ payload: false,
194
+ expiration: false,
195
+ owner: false,
196
+ },
197
+ },
198
+ ],
199
+ })
200
+ })
201
+
202
+ it("should process simple predicates with ownedBy", async () => {
203
+ const predicates = [{ type: "eq" as const, key: "key", value: "value" }]
204
+ await processQuery(client, {
205
+ predicates,
206
+ limit: undefined,
207
+ cursor: undefined,
208
+ ownedBy: "0x123",
209
+ })
210
+
211
+ expect(client.request).lastCalledWith({
212
+ method: "arkiv_query",
213
+ params: [
214
+ `key = "value" && $owner=0x123`,
215
+ {
216
+ includeData: {
217
+ key: true,
218
+ attributes: false,
219
+ contentType: false,
220
+ payload: false,
221
+ expiration: false,
222
+ owner: false,
223
+ },
224
+ },
225
+ ],
226
+ })
227
+ })
228
+
229
+ it("should process only ownedBy", async () => {
230
+ const predicates = [] as Predicate[]
231
+ await processQuery(client, {
232
+ predicates,
233
+ limit: undefined,
234
+ cursor: undefined,
235
+ validAtBlock: undefined,
236
+ withAttributes: undefined,
237
+ withMetadata: undefined,
238
+ ownedBy: "0x123",
239
+ })
240
+
241
+ expect(client.request).lastCalledWith({
242
+ method: "arkiv_query",
243
+ params: [
244
+ `$owner=0x123`,
245
+ {
246
+ includeData: {
247
+ key: true,
248
+ attributes: false,
249
+ contentType: false,
250
+ payload: false,
251
+ expiration: false,
252
+ owner: false,
253
+ },
254
+ },
255
+ ],
256
+ })
257
+ })
258
+
259
+ it("should process simple predicate with validAtBlock and paging", async () => {
260
+ const predicates = [{ type: "eq" as const, key: "key", value: "value" }]
261
+ await processQuery(client, {
262
+ predicates,
263
+ limit: 10,
264
+ cursor: undefined,
265
+ validAtBlock: 123n,
266
+ ownedBy: "0x123",
267
+ })
268
+
269
+ expect(client.request).lastCalledWith({
270
+ method: "arkiv_query",
271
+ params: [
272
+ `key = "value" && $owner=0x123`,
273
+ {
274
+ atBlock: 123,
275
+ resultsPerPage: 10,
276
+ includeData: {
277
+ key: true,
278
+ attributes: false,
279
+ contentType: false,
280
+ payload: false,
281
+ expiration: false,
282
+ owner: false,
283
+ },
284
+ },
285
+ ],
286
+ })
287
+ })
288
+ })
@@ -0,0 +1,112 @@
1
+ import type { Hex } from "viem"
2
+ import type { ArkivClient } from "../clients/baseClient"
3
+ import type { RpcQueryOptions } from "../types/rpcSchema"
4
+ import type { Predicate } from "./predicate"
5
+
6
+ function processPredicates(predicates: Predicate[]): string {
7
+ const processValue = (value: string | number) => {
8
+ if (typeof value === "string") {
9
+ return `"${value}"`
10
+ }
11
+ return value
12
+ }
13
+ return predicates
14
+ .map((predicate) => {
15
+ switch (predicate.type) {
16
+ case "eq":
17
+ return `${predicate.key} = ${processValue(predicate.value)}`
18
+ case "neq":
19
+ return `${predicate.key} != ${processValue(predicate.value)}`
20
+ case "gt":
21
+ return `${predicate.key} > ${processValue(predicate.value)}`
22
+ case "gte":
23
+ return `${predicate.key} >= ${processValue(predicate.value)}`
24
+ case "lt":
25
+ return `${predicate.key} < ${processValue(predicate.value)}`
26
+ case "lte":
27
+ return `${predicate.key} <= ${processValue(predicate.value)}`
28
+ case "not":
29
+ return `!${predicate.key}`
30
+ case "or":
31
+ return `(${predicate.predicates.map((predicate) => processPredicates([predicate])).join(" || ")})`
32
+ case "and":
33
+ return `(${predicate.predicates.map((predicate) => processPredicates([predicate])).join(" && ")})`
34
+ default:
35
+ return ""
36
+ }
37
+ })
38
+ .join(" && ")
39
+ }
40
+
41
+ export async function processQuery(
42
+ client: ArkivClient,
43
+ queryParams: {
44
+ predicates: Predicate[]
45
+ limit: number | undefined
46
+ cursor: string | undefined
47
+ ownedBy: Hex | undefined
48
+ validAtBlock?: bigint | undefined
49
+ withAttributes?: boolean | undefined
50
+ withMetadata?: boolean | undefined
51
+ withPayload?: boolean | undefined
52
+ },
53
+ ) {
54
+ const {
55
+ predicates,
56
+ limit,
57
+ cursor,
58
+ ownedBy,
59
+ validAtBlock,
60
+ withAttributes,
61
+ withMetadata,
62
+ withPayload,
63
+ } = queryParams
64
+
65
+ console.debug(
66
+ `Processing query with params: predicates: ${predicates}, cursor: ${cursor}, limit: ${limit}, ownedBy: ${ownedBy}, validAtBlock: ${validAtBlock}, withAttributes: ${withAttributes}, withMetadata: ${withMetadata}, withPayload: ${withPayload}`,
67
+ )
68
+
69
+ let query = processPredicates(predicates)
70
+ if (ownedBy) {
71
+ query += ` && $owner=${ownedBy}`
72
+ }
73
+
74
+ // remove leading and trailing spaces and leading &&
75
+ query = query.trim()
76
+ if (query.startsWith("&& ")) {
77
+ query = query.slice(3)
78
+ }
79
+
80
+ const queryOptions: RpcQueryOptions = {
81
+ includeData: {
82
+ key: true,
83
+ attributes: withAttributes ?? false,
84
+ payload: withPayload ?? false,
85
+ contentType: withMetadata ?? false,
86
+ expiration: withMetadata ?? false,
87
+ owner: withMetadata ?? false,
88
+ },
89
+ }
90
+
91
+ if (validAtBlock !== undefined) {
92
+ queryOptions.atBlock = Number(validAtBlock)
93
+ }
94
+ if (limit !== undefined) {
95
+ queryOptions.resultsPerPage = limit
96
+ }
97
+ if (cursor !== undefined) {
98
+ queryOptions.cursor = cursor
99
+ }
100
+
101
+ console.debug(
102
+ `Built query to send: ${query}, queryOptions: ${JSON.stringify({ includeData: queryOptions.includeData, atBlock: queryOptions.atBlock?.toString(), resultsPerPage: queryOptions.resultsPerPage, cursor: queryOptions.cursor })}`,
103
+ )
104
+
105
+ const result = await client.request({
106
+ method: "arkiv_query",
107
+ params: [query, queryOptions],
108
+ })
109
+ console.debug("Raw result from query: ", result)
110
+
111
+ return result
112
+ }
@@ -0,0 +1,23 @@
1
+ export class NoMoreResultsError extends Error {
2
+ constructor() {
3
+ super("No more results")
4
+ }
5
+ }
6
+
7
+ export class NoCursorOrLimitError extends Error {
8
+ constructor() {
9
+ super("Cursor and limit must be defined to fetch next")
10
+ }
11
+ }
12
+
13
+ export class OffsetCannotBeLessThanZeroError extends Error {
14
+ constructor() {
15
+ super("Offset cannot be less than 0")
16
+ }
17
+ }
18
+
19
+ export class NoEntityFoundError extends Error {
20
+ constructor() {
21
+ super("No entity found")
22
+ }
23
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./errors"
2
+ export * from "./predicate"
3
+ export * from "./queryBuilder"
4
+ export * from "./queryResult"