@arkiv-network/sdk 0.6.8-dev.5 → 0.7.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.
- package/dist/chains/index.d.ts +25 -25
- package/dist/consts-Bz0LZQZY.js +7 -0
- package/dist/consts-Bz0LZQZY.js.map +1 -0
- package/dist/{consts-AUoL-v42.cjs → consts-CxT1-RXU.cjs} +1 -1
- package/dist/entity-BhSXaB23.cjs +81 -0
- package/dist/{entity-B6g_EPm1.d.cts → entity-CN41IOrq.d.cts} +53 -34
- package/dist/entity-CN41IOrq.d.cts.map +1 -0
- package/dist/entity-DGfVyB-a.js +71 -0
- package/dist/entity-DGfVyB-a.js.map +1 -0
- package/dist/{entity-qoLMAuuk.d.ts → entity-NnEVlePN.d.ts} +53 -34
- package/dist/entity-NnEVlePN.d.ts.map +1 -0
- package/dist/{index-DdspxNAA.d.ts → index-ClkpS6s_.d.ts} +2 -2
- package/dist/{index-DdspxNAA.d.ts.map → index-ClkpS6s_.d.ts.map} +1 -1
- package/dist/{index-Ds9dwqb5.d.cts → index-w4qop0Pe.d.cts} +2 -2
- package/dist/{index-Ds9dwqb5.d.cts.map → index-w4qop0Pe.d.cts.map} +1 -1
- package/dist/index.cjs +281 -264
- package/dist/index.d.cts +13 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +14 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +279 -266
- package/dist/index.js.map +1 -1
- package/dist/{payload-Claf2jUO.js → payload-BpNUPOnY.js} +3 -3
- package/dist/payload-BpNUPOnY.js.map +1 -0
- package/dist/{payload-B2kFJyah.d.ts → payload-C2KHOUoj.d.ts} +1 -1
- package/dist/{payload-B2kFJyah.d.ts.map → payload-C2KHOUoj.d.ts.map} +1 -1
- package/dist/{payload-DpA5PA-w.cjs → payload-D8YLKcJj.cjs} +1 -1
- package/dist/query/index.cjs +3 -2
- package/dist/query/index.d.cts +2 -2
- package/dist/query/index.d.ts +2 -2
- package/dist/query/index.js +3 -2
- package/dist/query/index.js.map +1 -1
- package/dist/{queryBuilder-D2uwP9jI.js → queryBuilder-BE_XhLLa.js} +98 -67
- package/dist/queryBuilder-BE_XhLLa.js.map +1 -0
- package/dist/{queryBuilder-UW2MCaX4.cjs → queryBuilder-J37buGCi.cjs} +137 -64
- package/dist/types/index.cjs +4 -1
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +4 -1
- package/dist/utils/index.cjs +2 -2
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +2 -2
- package/package.json +1 -1
- package/src/actions/public/subscribeEntityEvents.ts +25 -51
- package/src/actions/wallet/changeOwnership.ts +6 -6
- package/src/actions/wallet/createEntity.ts +7 -4
- package/src/actions/wallet/deleteEntity.ts +2 -3
- package/src/actions/wallet/extendEntity.ts +3 -4
- package/src/actions/wallet/mutateEntities.ts +11 -54
- package/src/actions/wallet/updateEntity.ts +3 -4
- package/src/clients/decorators/arkivWallet.ts +5 -1
- package/src/consts.ts +2 -1
- package/src/errors.ts +29 -1
- package/src/query/engine.test.ts +45 -0
- package/src/query/engine.ts +6 -1
- package/src/query/selectQueryBuilder.test.ts +5 -2
- package/src/types/attributes.ts +17 -5
- package/src/types/entity.ts +12 -2
- package/src/types/events.ts +14 -16
- package/src/types/index.ts +1 -0
- package/src/types/rpcSchema.ts +7 -2
- package/src/utils/arkivTransactions.test.ts +234 -36
- package/src/utils/arkivTransactions.ts +255 -101
- package/src/utils/entities.ts +17 -7
- package/src/utils/payload.ts +4 -2
- package/src/utils/validation.test.ts +52 -6
- package/src/utils/validation.ts +54 -6
- package/dist/consts-BV4PR-de.js +0 -7
- package/dist/consts-BV4PR-de.js.map +0 -1
- package/dist/entity-B6g_EPm1.d.cts.map +0 -1
- package/dist/entity-qoLMAuuk.d.ts.map +0 -1
- package/dist/payload-Claf2jUO.js.map +0 -1
- package/dist/queryBuilder-D2uwP9jI.js.map +0 -1
- /package/dist/{types-H-TSmRpm.js → types-Ci4BRClw.js} +0 -0
- /package/dist/{types-o3zWarRp.cjs → types-a8gm_IaQ.cjs} +0 -0
package/dist/types/index.js
CHANGED
package/dist/utils/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_consts = require('../consts-
|
|
2
|
-
const require_payload = require('../payload-
|
|
1
|
+
const require_consts = require('../consts-CxT1-RXU.cjs');
|
|
2
|
+
const require_payload = require('../payload-D8YLKcJj.cjs');
|
|
3
3
|
|
|
4
4
|
//#region src/utils/expirationTime.ts
|
|
5
5
|
const ExpirationTime = {
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as BLOCK_TIME } from "../consts-
|
|
2
|
-
import { n as stringToPayload, t as jsonToPayload } from "../payload-
|
|
1
|
+
import { n as BLOCK_TIME } from "../consts-Bz0LZQZY.js";
|
|
2
|
+
import { n as stringToPayload, t as jsonToPayload } from "../payload-BpNUPOnY.js";
|
|
3
3
|
|
|
4
4
|
//#region src/utils/expirationTime.ts
|
|
5
5
|
const ExpirationTime = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { decodeEventLog, type Hex
|
|
1
|
+
import { decodeEventLog, type Hex } from "viem"
|
|
2
2
|
import type { ArkivClient } from "../../clients/baseClient"
|
|
3
3
|
import type { PublicArkivClient } from "../../clients/createPublicClient"
|
|
4
|
+
import { EntityOperationType } from "../../types/entity"
|
|
4
5
|
import type {
|
|
5
6
|
OnEntityCreatedEvent,
|
|
6
7
|
OnEntityDeletedEvent,
|
|
@@ -9,18 +10,12 @@ import type {
|
|
|
9
10
|
OnEntityOwnerChangedEvent,
|
|
10
11
|
OnEntityUpdatedEvent,
|
|
11
12
|
} from "../../types/events"
|
|
13
|
+
import { ENTITY_OPERATION_EVENT_ABI } from "../../utils/arkivTransactions"
|
|
12
14
|
import { getLogger } from "../../utils/logger"
|
|
13
15
|
|
|
14
16
|
const logger = getLogger("actions:public:subscribe-entity-events")
|
|
15
17
|
|
|
16
|
-
export const arkivABI =
|
|
17
|
-
"event ArkivEntityCreated(uint256 indexed entityKey, address indexed ownerAddress, uint256 expirationBlock, uint256 cost)",
|
|
18
|
-
"event ArkivEntityUpdated(uint256 indexed entityKey, address indexed ownerAddress, uint256 oldExpirationBlock, uint256 newExpirationBlock, uint256 cost)",
|
|
19
|
-
"event ArkivEntityExpired(uint256 indexed entityKey, address indexed ownerAddress)",
|
|
20
|
-
"event ArkivEntityDeleted(uint256 indexed entityKey, address indexed ownerAddress)",
|
|
21
|
-
"event ArkivEntityBTLExtended(uint256 indexed entityKey, address indexed ownerAddress, uint256 oldExpirationBlock, uint256 newExpirationBlock, uint256 cost)",
|
|
22
|
-
"event ArkivEntityOwnerChanged(uint256 indexed entityKey, address indexed oldOwnerAddress, address indexed newOwnerAddress)",
|
|
23
|
-
])
|
|
18
|
+
export const arkivABI = ENTITY_OPERATION_EVENT_ABI
|
|
24
19
|
|
|
25
20
|
export async function subscribeEntityEvents(
|
|
26
21
|
client: ArkivClient,
|
|
@@ -57,54 +52,33 @@ export async function subscribeEntityEvents(
|
|
|
57
52
|
data: log.data,
|
|
58
53
|
})
|
|
59
54
|
logger("event from subscribeEntityEvents %o", event)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
owner: event.args.ownerAddress,
|
|
73
|
-
oldExpirationBlock: Number(event.args.oldExpirationBlock),
|
|
74
|
-
newExpirationBlock: Number(event.args.newExpirationBlock),
|
|
75
|
-
cost: event.args.cost,
|
|
76
|
-
})
|
|
55
|
+
|
|
56
|
+
if (event.eventName !== "EntityOperation") continue
|
|
57
|
+
|
|
58
|
+
const entityKey = event.args.entityKey as Hex
|
|
59
|
+
const owner = event.args.owner
|
|
60
|
+
const expiresAt = event.args.expiresAt
|
|
61
|
+
const entityHash = event.args.entityHash as Hex
|
|
62
|
+
const opType = Number(event.args.operationType)
|
|
63
|
+
|
|
64
|
+
switch (opType) {
|
|
65
|
+
case EntityOperationType.Create:
|
|
66
|
+
onEntityCreated?.({ entityKey, owner, expiresAt, entityHash })
|
|
77
67
|
break
|
|
78
|
-
case
|
|
79
|
-
|
|
80
|
-
entityKey: toHex(event.args.entityKey, { size: 32 }),
|
|
81
|
-
owner: event.args.ownerAddress,
|
|
82
|
-
})
|
|
68
|
+
case EntityOperationType.Update:
|
|
69
|
+
onEntityUpdated?.({ entityKey, owner, expiresAt, entityHash })
|
|
83
70
|
break
|
|
84
|
-
case
|
|
85
|
-
onEntityExpiresInExtended?.({
|
|
86
|
-
entityKey: toHex(event.args.entityKey, { size: 32 }),
|
|
87
|
-
owner: event.args.ownerAddress,
|
|
88
|
-
oldExpirationBlock: Number(event.args.oldExpirationBlock),
|
|
89
|
-
newExpirationBlock: Number(event.args.newExpirationBlock),
|
|
90
|
-
cost: event.args.cost,
|
|
91
|
-
})
|
|
71
|
+
case EntityOperationType.Extend:
|
|
72
|
+
onEntityExpiresInExtended?.({ entityKey, owner, expiresAt, entityHash })
|
|
92
73
|
break
|
|
93
|
-
case
|
|
94
|
-
|
|
95
|
-
entityKey: toHex(event.args.entityKey, { size: 32 }),
|
|
96
|
-
owner: event.args.ownerAddress,
|
|
97
|
-
})
|
|
74
|
+
case EntityOperationType.Transfer:
|
|
75
|
+
onEntityOwnerChanged?.({ entityKey, owner, entityHash })
|
|
98
76
|
break
|
|
99
|
-
case
|
|
100
|
-
|
|
101
|
-
entityKey: toHex(event.args.entityKey, { size: 32 }),
|
|
102
|
-
oldOwner: event.args.oldOwnerAddress,
|
|
103
|
-
newOwner: event.args.newOwnerAddress,
|
|
104
|
-
})
|
|
77
|
+
case EntityOperationType.Delete:
|
|
78
|
+
onEntityDeleted?.({ entityKey, owner })
|
|
105
79
|
break
|
|
106
80
|
default:
|
|
107
|
-
|
|
81
|
+
onEntityExpired?.({ entityKey, owner })
|
|
108
82
|
break
|
|
109
83
|
}
|
|
110
84
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { Hex } from "viem"
|
|
2
2
|
import type { ArkivClient } from "../../clients/baseClient"
|
|
3
3
|
import type { TxParams } from "../../types"
|
|
4
|
-
import {
|
|
4
|
+
import { sendArkivTransaction } from "../../utils/arkivTransactions"
|
|
5
5
|
import { getLogger } from "../../utils/logger"
|
|
6
6
|
|
|
7
7
|
const logger = getLogger("actions:wallet:change-ownership")
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Parameters for the
|
|
11
|
-
* - entityKey: The key of the entity
|
|
10
|
+
* Parameters for the changeOwnership function.
|
|
11
|
+
* - entityKey: The key of the entity.
|
|
12
|
+
* - newOwner: The address of the new owner.
|
|
12
13
|
*/
|
|
13
14
|
export type ChangeOwnershipParameters = {
|
|
14
15
|
entityKey: Hex
|
|
@@ -16,7 +17,7 @@ export type ChangeOwnershipParameters = {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
|
-
* Return type for the
|
|
20
|
+
* Return type for the changeOwnership function.
|
|
20
21
|
* - entityKey: The key of the entity.
|
|
21
22
|
* - txHash: The transaction hash.
|
|
22
23
|
*/
|
|
@@ -31,8 +32,7 @@ export async function changeOwnership(
|
|
|
31
32
|
txParams?: TxParams,
|
|
32
33
|
): Promise<ChangeOwnershipReturnType> {
|
|
33
34
|
logger("changeOwnership %o", data)
|
|
34
|
-
const
|
|
35
|
-
const receipt = await sendArkivTransaction(client, txData, txParams)
|
|
35
|
+
const { receipt } = await sendArkivTransaction(client, { ownershipChanges: [data] }, txParams)
|
|
36
36
|
|
|
37
37
|
logger("Receipt from changeOwnership %o", receipt)
|
|
38
38
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Hash, Hex } from "viem"
|
|
2
2
|
import type { ArkivClient } from "../../clients/baseClient"
|
|
3
3
|
import type { Attribute, MimeType, TxParams } from "../../types"
|
|
4
|
-
import {
|
|
4
|
+
import { sendArkivTransaction } from "../../utils/arkivTransactions"
|
|
5
5
|
import { getLogger } from "../../utils/logger"
|
|
6
6
|
|
|
7
7
|
const logger = getLogger("actions:wallet:create-entity")
|
|
@@ -46,13 +46,16 @@ export async function createEntity(
|
|
|
46
46
|
txParams?: TxParams,
|
|
47
47
|
): Promise<CreateEntityReturnType> {
|
|
48
48
|
logger("createEntity %o", data)
|
|
49
|
-
const
|
|
50
|
-
|
|
49
|
+
const { receipt, createdEntityKeys } = await sendArkivTransaction(
|
|
50
|
+
client,
|
|
51
|
+
{ creates: [data] },
|
|
52
|
+
txParams,
|
|
53
|
+
)
|
|
51
54
|
|
|
52
55
|
logger("Receipt from createEntity %o", receipt)
|
|
53
56
|
|
|
54
57
|
return {
|
|
55
58
|
txHash: receipt.transactionHash as Hash,
|
|
56
|
-
entityKey:
|
|
59
|
+
entityKey: createdEntityKeys[0],
|
|
57
60
|
}
|
|
58
61
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Hash, Hex } from "viem"
|
|
2
2
|
import type { ArkivClient } from "../../clients/baseClient"
|
|
3
3
|
import type { TxParams } from "../../types"
|
|
4
|
-
import {
|
|
4
|
+
import { sendArkivTransaction } from "../../utils/arkivTransactions"
|
|
5
5
|
import { getLogger } from "../../utils/logger"
|
|
6
6
|
|
|
7
7
|
const logger = getLogger("actions:wallet:delete-entity")
|
|
@@ -30,8 +30,7 @@ export async function deleteEntity(
|
|
|
30
30
|
txParams?: TxParams,
|
|
31
31
|
): Promise<DeleteEntityReturnType> {
|
|
32
32
|
logger("deleteEntity %o", data)
|
|
33
|
-
const
|
|
34
|
-
const receipt = await sendArkivTransaction(client, txData, txParams)
|
|
33
|
+
const { receipt } = await sendArkivTransaction(client, { deletes: [data] }, txParams)
|
|
35
34
|
|
|
36
35
|
logger("Receipt from deleteEntity %o", receipt)
|
|
37
36
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Hash, Hex } from "viem"
|
|
2
2
|
import type { ArkivClient } from "../../clients/baseClient"
|
|
3
3
|
import type { TxParams } from "../../types"
|
|
4
|
-
import {
|
|
4
|
+
import { sendArkivTransaction } from "../../utils/arkivTransactions"
|
|
5
5
|
import { getLogger } from "../../utils/logger"
|
|
6
6
|
|
|
7
7
|
const logger = getLogger("actions:wallet:extend-entity")
|
|
@@ -37,13 +37,12 @@ export async function extendEntity(
|
|
|
37
37
|
txParams?: TxParams,
|
|
38
38
|
): Promise<ExtendEntityReturnType> {
|
|
39
39
|
logger("extendEntity %o", data)
|
|
40
|
-
const
|
|
41
|
-
const receipt = await sendArkivTransaction(client, txData, txParams)
|
|
40
|
+
const { receipt } = await sendArkivTransaction(client, { extensions: [data] }, txParams)
|
|
42
41
|
|
|
43
42
|
logger("Receipt from extendEntity %o", receipt)
|
|
44
43
|
|
|
45
44
|
return {
|
|
46
45
|
txHash: receipt.transactionHash as Hash,
|
|
47
|
-
entityKey:
|
|
46
|
+
entityKey: data.entityKey,
|
|
48
47
|
}
|
|
49
48
|
}
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import type { Hash, Hex
|
|
1
|
+
import type { Hash, Hex } from "viem"
|
|
2
2
|
import type { ArkivClient } from "../../clients/baseClient"
|
|
3
3
|
import type { TxParams } from "../../types"
|
|
4
|
-
import {
|
|
4
|
+
import { sendArkivTransaction } from "../../utils/arkivTransactions"
|
|
5
5
|
import { getLogger } from "../../utils/logger"
|
|
6
6
|
import type { ChangeOwnershipParameters } from "./changeOwnership"
|
|
7
|
-
|
|
8
|
-
const logger = getLogger("actions:wallet:mutate-entities")
|
|
9
|
-
|
|
10
7
|
import type { CreateEntityParameters } from "./createEntity"
|
|
11
8
|
import type { DeleteEntityParameters } from "./deleteEntity"
|
|
12
9
|
import type { ExtendEntityParameters } from "./extendEntity"
|
|
13
10
|
import type { UpdateEntityParameters } from "./updateEntity"
|
|
14
11
|
|
|
12
|
+
const logger = getLogger("actions:wallet:mutate-entities")
|
|
13
|
+
|
|
15
14
|
/**
|
|
16
15
|
* Parameters for the mutateEntities function.
|
|
17
16
|
* - creates: The creates to perform.
|
|
@@ -27,39 +26,6 @@ export type MutateEntitiesParameters = {
|
|
|
27
26
|
ownershipChanges?: ChangeOwnershipParameters[]
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
function parseReceipt(receipt: TransactionReceipt, params: MutateEntitiesParameters) {
|
|
31
|
-
const createdEntities: Hex[] = []
|
|
32
|
-
const updatedEntities: Hex[] = []
|
|
33
|
-
const deletedEntities: Hex[] = []
|
|
34
|
-
const extendedEntities: Hex[] = []
|
|
35
|
-
const ownershipChanges: Hex[] = []
|
|
36
|
-
|
|
37
|
-
const totalCreates = params.creates?.length ?? 0
|
|
38
|
-
const totalUpdates = params.updates?.length ?? 0
|
|
39
|
-
const totalDeletes = params.deletes?.length ?? 0
|
|
40
|
-
const totalExtensions = params.extensions?.length ?? 0
|
|
41
|
-
|
|
42
|
-
// iterate over all logs and parse the event
|
|
43
|
-
// logs go in the following order: creates, deleted, updates, extends, ownership changes
|
|
44
|
-
for (let index = 0; index < receipt.logs.length; index++) {
|
|
45
|
-
const log = receipt.logs[index]
|
|
46
|
-
|
|
47
|
-
if (index < totalCreates) {
|
|
48
|
-
createdEntities.push(log.topics[1] as Hex)
|
|
49
|
-
} else if (index < totalCreates + totalDeletes) {
|
|
50
|
-
deletedEntities.push(log.topics[1] as Hex)
|
|
51
|
-
} else if (index < totalCreates + totalUpdates + totalDeletes) {
|
|
52
|
-
updatedEntities.push(log.topics[1] as Hex)
|
|
53
|
-
} else if (index < totalCreates + totalUpdates + totalDeletes + totalExtensions) {
|
|
54
|
-
extendedEntities.push(log.topics[1] as Hex)
|
|
55
|
-
} else {
|
|
56
|
-
ownershipChanges.push(log.topics[1] as Hex)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return { createdEntities, updatedEntities, deletedEntities, extendedEntities, ownershipChanges }
|
|
61
|
-
}
|
|
62
|
-
|
|
63
29
|
/**
|
|
64
30
|
* Return type for the mutateEntities function.
|
|
65
31
|
* - txHash: The transaction hash.
|
|
@@ -77,6 +43,7 @@ export type MutateEntitiesReturnType = {
|
|
|
77
43
|
extendedEntities: Hex[]
|
|
78
44
|
ownershipChanges: Hex[]
|
|
79
45
|
}
|
|
46
|
+
|
|
80
47
|
export async function mutateEntities(
|
|
81
48
|
client: ArkivClient,
|
|
82
49
|
data: MutateEntitiesParameters,
|
|
@@ -86,26 +53,16 @@ export async function mutateEntities(
|
|
|
86
53
|
throw new Error("No operations to perform")
|
|
87
54
|
}
|
|
88
55
|
|
|
89
|
-
const
|
|
90
|
-
creates: data.creates ?? [],
|
|
91
|
-
updates: data.updates ?? [],
|
|
92
|
-
deletes: data.deletes ?? [],
|
|
93
|
-
extensions: data.extensions ?? [],
|
|
94
|
-
ownershipChanges: data.ownershipChanges ?? [],
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
const receipt = await sendArkivTransaction(client, txData, txParams)
|
|
56
|
+
const { receipt, createdEntityKeys } = await sendArkivTransaction(client, data, txParams)
|
|
98
57
|
|
|
99
58
|
logger("Receipt from mutateEntities %o", receipt)
|
|
100
59
|
|
|
101
|
-
const { createdEntities, updatedEntities, deletedEntities, extendedEntities, ownershipChanges } =
|
|
102
|
-
parseReceipt(receipt, data)
|
|
103
60
|
return {
|
|
104
61
|
txHash: receipt.transactionHash as Hash,
|
|
105
|
-
createdEntities,
|
|
106
|
-
updatedEntities,
|
|
107
|
-
deletedEntities,
|
|
108
|
-
extendedEntities,
|
|
109
|
-
ownershipChanges,
|
|
62
|
+
createdEntities: createdEntityKeys,
|
|
63
|
+
updatedEntities: (data.updates ?? []).map((u) => u.entityKey),
|
|
64
|
+
deletedEntities: (data.deletes ?? []).map((d) => d.entityKey),
|
|
65
|
+
extendedEntities: (data.extensions ?? []).map((e) => e.entityKey),
|
|
66
|
+
ownershipChanges: (data.ownershipChanges ?? []).map((o) => o.entityKey),
|
|
110
67
|
}
|
|
111
68
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Hash, Hex } from "viem"
|
|
2
2
|
import type { ArkivClient } from "../../clients/baseClient"
|
|
3
3
|
import type { Attribute, MimeType, TxParams } from "../../types"
|
|
4
|
-
import {
|
|
4
|
+
import { sendArkivTransaction } from "../../utils/arkivTransactions"
|
|
5
5
|
import { getLogger } from "../../utils/logger"
|
|
6
6
|
|
|
7
7
|
const logger = getLogger("actions:wallet:update-entity")
|
|
@@ -48,13 +48,12 @@ export async function updateEntity(
|
|
|
48
48
|
txParams?: TxParams,
|
|
49
49
|
): Promise<UpdateEntityReturnType> {
|
|
50
50
|
logger("updateEntity %o", data)
|
|
51
|
-
const
|
|
52
|
-
const receipt = await sendArkivTransaction(client, txData, txParams)
|
|
51
|
+
const { receipt } = await sendArkivTransaction(client, { updates: [data] }, txParams)
|
|
53
52
|
|
|
54
53
|
logger("Receipt from updateEntity %o", receipt)
|
|
55
54
|
|
|
56
55
|
return {
|
|
57
56
|
txHash: receipt.transactionHash as Hash,
|
|
58
|
-
entityKey:
|
|
57
|
+
entityKey: data.entityKey,
|
|
59
58
|
}
|
|
60
59
|
}
|
|
@@ -35,7 +35,10 @@ export type WalletArkivActions<
|
|
|
35
35
|
transport extends Transport = Transport,
|
|
36
36
|
chain extends Chain | undefined = Chain | undefined,
|
|
37
37
|
account extends Account | undefined = Account | undefined,
|
|
38
|
-
> = Pick<
|
|
38
|
+
> = Pick<
|
|
39
|
+
PublicActions<transport, chain, account>,
|
|
40
|
+
"waitForTransactionReceipt" | "call" | "simulateContract" | "readContract" | "getBlockNumber"
|
|
41
|
+
> &
|
|
39
42
|
Pick<
|
|
40
43
|
WalletActions<chain, account>,
|
|
41
44
|
| "addChain"
|
|
@@ -45,6 +48,7 @@ export type WalletArkivActions<
|
|
|
45
48
|
| "sendRawTransaction"
|
|
46
49
|
| "signMessage"
|
|
47
50
|
| "signTransaction"
|
|
51
|
+
| "writeContract"
|
|
48
52
|
> & {
|
|
49
53
|
/**
|
|
50
54
|
* Creates a new entity.
|
package/src/consts.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export const ARKIV_ADDRESS = "0x00000000000000000000000000000061726b6976" as `0x${string}`
|
|
1
|
+
//export const ARKIV_ADDRESS = "0x00000000000000000000000000000061726b6976" as `0x${string}`
|
|
2
|
+
export const ARKIV_ADDRESS = "0x4400000000000000000000000000000000000044" as `0x${string}`
|
|
2
3
|
export const BLOCK_TIME = 2 // 2 seconds
|
package/src/errors.ts
CHANGED
|
@@ -16,13 +16,32 @@ export class InvalidExpirationError extends Error {
|
|
|
16
16
|
}
|
|
17
17
|
export class InvalidAttributeError extends Error {
|
|
18
18
|
constructor(key: string, value: number) {
|
|
19
|
+
const remedy = Number.isInteger(value)
|
|
20
|
+
? `Offset it into the non-negative range (e.g. store ${String(value)} + OFFSET, subtracting OFFSET on read) to keep numeric ordering/range queries; otherwise store it as a string (e.g. "${String(value)}")`
|
|
21
|
+
: `To keep numeric ordering/range queries, scale it to an integer (e.g. Math.round(${String(value)} * 1000), dividing by 1000 on read); otherwise store it as a string (e.g. "${String(value)}")`
|
|
19
22
|
super(
|
|
20
|
-
`Invalid numeric value for attribute "${key}": ${String(value)}. Numeric attribute values must be integers
|
|
23
|
+
`Invalid numeric value for attribute "${key}": ${String(value)}. Numeric attribute values must be non-negative integers (stored on-chain as unsigned 256-bit). ${remedy}.`,
|
|
21
24
|
)
|
|
22
25
|
this.name = "InvalidAttributeError"
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
|
|
29
|
+
export class InvalidAttributeKeyError extends Error {
|
|
30
|
+
constructor(key: string, reason: string) {
|
|
31
|
+
super(
|
|
32
|
+
`Invalid attribute key "${key}": ${reason}. Keys must be 1-32 bytes, start with a lowercase letter (a-z), and contain only a-z, 0-9, ".", "-" or "_".`,
|
|
33
|
+
)
|
|
34
|
+
this.name = "InvalidAttributeKeyError"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class DuplicateAttributeError extends Error {
|
|
39
|
+
constructor(key: string) {
|
|
40
|
+
super(`Duplicate attribute key "${key}". Attribute keys must be unique per entity.`)
|
|
41
|
+
this.name = "DuplicateAttributeError"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
26
45
|
export class NoMoreResultsError extends Error {
|
|
27
46
|
constructor() {
|
|
28
47
|
super("No more results")
|
|
@@ -43,3 +62,12 @@ export class NoEntityFoundError extends Error {
|
|
|
43
62
|
this.name = "NoEntityFoundError"
|
|
44
63
|
}
|
|
45
64
|
}
|
|
65
|
+
|
|
66
|
+
export class InvalidContentTypeError extends Error {
|
|
67
|
+
constructor(contentType: string) {
|
|
68
|
+
super(
|
|
69
|
+
`Invalid content type "${contentType}". Must follow RFC 2045 MIME grammar and be lowercase only (e.g. "text/plain").`,
|
|
70
|
+
)
|
|
71
|
+
this.name = "InvalidContentTypeError"
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/query/engine.test.ts
CHANGED
|
@@ -47,6 +47,51 @@ describe("processQuery tests", () => {
|
|
|
47
47
|
})
|
|
48
48
|
})
|
|
49
49
|
|
|
50
|
+
it("should serialize 32-byte hex values as unquoted literals and other hex as strings", async () => {
|
|
51
|
+
const hexValue = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
|
52
|
+
const predicates = [
|
|
53
|
+
{ type: "eq" as const, key: "hexattr", value: hexValue },
|
|
54
|
+
{ type: "eq" as const, key: "strattr", value: "value" },
|
|
55
|
+
// hex-looking but not 32 bytes — stored as strings, so compared quoted
|
|
56
|
+
{ type: "eq" as const, key: "shorthex", value: "0xab" },
|
|
57
|
+
{ type: "eq" as const, key: "addrhex", value: "0x6186b0dba9652262942d5a465d49686eb560834c" },
|
|
58
|
+
]
|
|
59
|
+
await processQuery(client, {
|
|
60
|
+
predicates,
|
|
61
|
+
limit: undefined,
|
|
62
|
+
cursor: undefined,
|
|
63
|
+
ownedBy: undefined,
|
|
64
|
+
createdBy: undefined,
|
|
65
|
+
orderBy: undefined,
|
|
66
|
+
validAtBlock: undefined,
|
|
67
|
+
withAttributes: undefined,
|
|
68
|
+
withMetadata: undefined,
|
|
69
|
+
withPayload: undefined,
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
expect(client.request).lastCalledWith({
|
|
73
|
+
method: "arkiv_query",
|
|
74
|
+
params: [
|
|
75
|
+
`hexattr = ${hexValue} && strattr = "value" && shorthex = "0xab" && addrhex = "0x6186b0dba9652262942d5a465d49686eb560834c"`,
|
|
76
|
+
{
|
|
77
|
+
includeData: {
|
|
78
|
+
key: true,
|
|
79
|
+
attributes: false,
|
|
80
|
+
contentType: false,
|
|
81
|
+
payload: false,
|
|
82
|
+
expiration: false,
|
|
83
|
+
owner: false,
|
|
84
|
+
creator: false,
|
|
85
|
+
createdAtBlock: false,
|
|
86
|
+
lastModifiedAtBlock: false,
|
|
87
|
+
transactionIndexInBlock: false,
|
|
88
|
+
operationIndexInTransaction: false,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
50
95
|
it("should process all simple predicates - flat", async () => {
|
|
51
96
|
const predicates = [
|
|
52
97
|
{ type: "eq" as const, key: "key", value: "value" },
|
package/src/query/engine.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { hexToNumber, numberToHex } from "viem"
|
|
|
3
3
|
import type { ArkivClient } from "../clients/baseClient"
|
|
4
4
|
import type { RpcIncludeData, RpcOrderByAttribute, RpcQueryOptions } from "../types/rpcSchema"
|
|
5
5
|
import { getLogger } from "../utils/logger"
|
|
6
|
+
import { isEntityKey } from "../utils/validation"
|
|
6
7
|
import type { Predicate } from "./predicate"
|
|
7
8
|
|
|
8
9
|
const logger = getLogger("query:engine")
|
|
@@ -10,7 +11,11 @@ const logger = getLogger("query:engine")
|
|
|
10
11
|
function processPredicates(predicates: Predicate[]): string {
|
|
11
12
|
const processValue = (value: string | number) => {
|
|
12
13
|
if (typeof value === "string") {
|
|
13
|
-
|
|
14
|
+
// 32-byte hex strings are stored as the EntityKey attribute type (see
|
|
15
|
+
// encodeAttribute), which the query language only matches against unquoted
|
|
16
|
+
// hex literals. All other strings — including shorter hex — are stored and
|
|
17
|
+
// compared as quoted strings.
|
|
18
|
+
return isEntityKey(value) ? value : `"${value}"`
|
|
14
19
|
}
|
|
15
20
|
return value
|
|
16
21
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, jest, test } from "bun:test"
|
|
2
2
|
import type { ArkivClient } from "../clients/baseClient"
|
|
3
3
|
import type { Entity } from "../types/entity"
|
|
4
|
+
import { RpcAttributeValueType } from "../types/rpcSchema"
|
|
4
5
|
import * as entitiesUtils from "../utils/entities"
|
|
5
6
|
import * as engine from "./engine"
|
|
6
7
|
import { eq, gte } from "./predicate"
|
|
@@ -150,8 +151,10 @@ describe("SelectQueryBuilder", () => {
|
|
|
150
151
|
key: "0xabc",
|
|
151
152
|
owner: "0xowner",
|
|
152
153
|
value: "0x68656c6c6f", // "hello"
|
|
153
|
-
|
|
154
|
-
|
|
154
|
+
attributes: [
|
|
155
|
+
{ key: "category", value: "docs", valueType: RpcAttributeValueType.String },
|
|
156
|
+
{ key: "score", value: "0x2a", valueType: RpcAttributeValueType.Uint },
|
|
157
|
+
],
|
|
155
158
|
},
|
|
156
159
|
],
|
|
157
160
|
cursor: "",
|
package/src/types/attributes.ts
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
|
+
import type { Hex } from "viem"
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* An entity attribute (key/value pair).
|
|
3
5
|
*
|
|
4
|
-
* Arkiv supports
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* Arkiv supports string, Hex and number values.
|
|
7
|
+
*
|
|
8
|
+
* Hex values are stored as the on-chain `EntityKey` type **only when they are
|
|
9
|
+
* exactly 32 bytes** (66 characters, e.g. an entity key). Hex-looking strings
|
|
10
|
+
* of any other length are stored as plain strings: they round-trip unchanged
|
|
11
|
+
* and compare lexicographically, not as hex.
|
|
12
|
+
*
|
|
13
|
+
* Numeric values **must be non-negative integers** (they are stored on-chain
|
|
14
|
+
* as unsigned 256-bit) — passing a non-integer (e.g. `1.5`) or negative number
|
|
15
|
+
* throws an {@link InvalidAttributeError} at mutation time. To store a
|
|
16
|
+
* non-integer value:
|
|
7
17
|
* - Scale it to an integer (e.g. `1.5` -> `1500`, dividing by the same factor on
|
|
8
18
|
* read) to keep numeric ordering and range queries working.
|
|
9
19
|
* - Or pass it as a string (e.g. `"1.5"`), which sorts lexicographically and so
|
|
10
20
|
* does not support numeric comparisons.
|
|
21
|
+
*
|
|
22
|
+
* To store a negative value, offset it into the non-negative range (subtracting
|
|
23
|
+
* the offset on read) or store it as a string.
|
|
11
24
|
*/
|
|
12
25
|
export type Attribute = {
|
|
13
26
|
key: string
|
|
14
|
-
|
|
15
|
-
value: string | number
|
|
27
|
+
value: number | string | Hex
|
|
16
28
|
}
|
package/src/types/entity.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import { bytesToString, type Hex } from "viem"
|
|
2
|
+
|
|
3
|
+
export enum EntityOperationType {
|
|
4
|
+
Create = 1,
|
|
5
|
+
Update = 2,
|
|
6
|
+
Extend = 3,
|
|
7
|
+
Transfer = 4,
|
|
8
|
+
Delete = 5,
|
|
9
|
+
Expire = 6,
|
|
10
|
+
}
|
|
11
|
+
|
|
2
12
|
import type { MimeType } from "../types"
|
|
3
13
|
import type { Attribute } from "./attributes"
|
|
4
14
|
|
|
5
15
|
export class Entity {
|
|
6
16
|
key: Hex
|
|
7
|
-
contentType: MimeType | undefined
|
|
17
|
+
contentType: MimeType | `${string}/${string}` | undefined
|
|
8
18
|
owner: Hex | undefined
|
|
9
19
|
creator: Hex | undefined
|
|
10
20
|
expiresAtBlock: bigint | undefined
|
|
@@ -17,7 +27,7 @@ export class Entity {
|
|
|
17
27
|
|
|
18
28
|
constructor(
|
|
19
29
|
key: Hex,
|
|
20
|
-
contentType: MimeType | undefined = undefined,
|
|
30
|
+
contentType: MimeType | `${string}/${string}` | undefined = undefined,
|
|
21
31
|
owner: Hex | undefined = undefined,
|
|
22
32
|
creator: Hex | undefined = undefined,
|
|
23
33
|
expiresAtBlock: bigint | undefined = undefined,
|