@arkiv-network/sdk 0.7.0 → 0.8.0-advanced.2
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/README.md +71 -16
- package/dist/actions/advanced/index.cjs +13 -0
- package/dist/actions/advanced/index.d.cts +8 -0
- package/dist/actions/advanced/index.d.ts +9 -0
- package/dist/actions/advanced/index.js +9 -0
- package/dist/advanced-8ZPTmmaN.js +598 -0
- package/dist/advanced-8ZPTmmaN.js.map +1 -0
- package/dist/advanced-fPImL6lW.cjs +656 -0
- package/dist/arkivTransactions-D74gERHG.d.cts +571 -0
- package/dist/arkivTransactions-D74gERHG.d.cts.map +1 -0
- package/dist/arkivTransactions-NtGD6uk5.d.ts +571 -0
- package/dist/arkivTransactions-NtGD6uk5.d.ts.map +1 -0
- package/dist/attr/index.cjs +35 -0
- package/dist/attr/index.d.cts +2 -0
- package/dist/attr/index.d.ts +3 -0
- package/dist/attr/index.js +4 -0
- package/dist/attributes-BhY5DwJp.js +809 -0
- package/dist/attributes-BhY5DwJp.js.map +1 -0
- package/dist/attributes-Df9IsCVs.cjs +1029 -0
- package/dist/chains/index.cjs +2 -3
- package/dist/chains/index.d.cts +39 -77
- package/dist/chains/index.d.cts.map +1 -1
- package/dist/chains/index.d.ts +22 -60
- package/dist/chains/index.d.ts.map +1 -1
- package/dist/chains/index.js +2 -2
- package/dist/chains-BJrZs6sG.js +57 -0
- package/dist/chains-BJrZs6sG.js.map +1 -0
- package/dist/chains-BYRTTipa.cjs +73 -0
- package/dist/codec-Car3KkFF.d.ts +102 -0
- package/dist/codec-Car3KkFF.d.ts.map +1 -0
- package/dist/entity/index.cjs +20 -0
- package/dist/entity/index.d.cts +4 -0
- package/dist/entity/index.d.ts +5 -0
- package/dist/entity/index.js +7 -0
- package/dist/entity-B00Li04j.cjs +71 -0
- package/dist/entity-B7G8q_Eo.cjs +0 -0
- package/dist/entity-BYQR1uoe.js +67 -0
- package/dist/entity-BYQR1uoe.js.map +1 -0
- package/dist/entity-CD_qFF2M.js +0 -0
- package/dist/errors-BVbjKVMN.cjs +56 -0
- package/dist/errors-LTe7bOYS.js +33 -0
- package/dist/errors-LTe7bOYS.js.map +1 -0
- package/dist/expiry-BELY2Kpw.cjs +135 -0
- package/dist/expiry-BjpxZZQU.js +95 -0
- package/dist/expiry-BjpxZZQU.js.map +1 -0
- package/dist/expiry-DRV29F1r.d.cts +79 -0
- package/dist/expiry-DRV29F1r.d.cts.map +1 -0
- package/dist/expiry-nDbCgZX4.d.ts +79 -0
- package/dist/expiry-nDbCgZX4.d.ts.map +1 -0
- package/dist/flags-5dTNRnow.d.ts +41 -0
- package/dist/flags-5dTNRnow.d.ts.map +1 -0
- package/dist/flags-CRjPpoh3.d.cts +41 -0
- package/dist/flags-CRjPpoh3.d.cts.map +1 -0
- package/dist/flags-DFBs2J94.js +33 -0
- package/dist/flags-DFBs2J94.js.map +1 -0
- package/dist/flags-kr276q6i.cjs +43 -0
- package/dist/index-B5j76711.d.ts +184 -0
- package/dist/index-B5j76711.d.ts.map +1 -0
- package/dist/index-BF7Mq9Is.d.cts +280 -0
- package/dist/index-BF7Mq9Is.d.cts.map +1 -0
- package/dist/index-CA4V7Pdh.d.cts +167 -0
- package/dist/index-CA4V7Pdh.d.cts.map +1 -0
- package/dist/index-CV5zCdpa.d.cts +417 -0
- package/dist/index-CV5zCdpa.d.cts.map +1 -0
- package/dist/index-DHDud2hC.d.ts +280 -0
- package/dist/index-DHDud2hC.d.ts.map +1 -0
- package/dist/index-DvYvrkdk.d.ts +320 -0
- package/dist/index-DvYvrkdk.d.ts.map +1 -0
- package/dist/index-EeUO0nnJ.d.cts +184 -0
- package/dist/index-EeUO0nnJ.d.cts.map +1 -0
- package/dist/index-fX_XyqLp.d.ts +167 -0
- package/dist/index-fX_XyqLp.d.ts.map +1 -0
- package/dist/index.cjs +422 -399
- package/dist/index.d.cts +364 -204
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +365 -204
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +357 -389
- package/dist/index.js.map +1 -1
- package/dist/key-D1Bh7MF0.js +70 -0
- package/dist/key-D1Bh7MF0.js.map +1 -0
- package/dist/key-WKhXnXuU.cjs +98 -0
- package/dist/logger-CVpvU8ik.js +153 -0
- package/dist/logger-CVpvU8ik.js.map +1 -0
- package/dist/logger-Cr15lPAQ.cjs +188 -0
- package/dist/payload-BNoud2KZ.d.cts +94 -0
- package/dist/payload-BNoud2KZ.d.cts.map +1 -0
- package/dist/payload-Bz6651ax.js +67 -0
- package/dist/payload-Bz6651ax.js.map +1 -0
- package/dist/payload-CcUj85ys.d.ts +94 -0
- package/dist/payload-CcUj85ys.d.ts.map +1 -0
- package/dist/payload-KC14SDlN.cjs +83 -0
- package/dist/query/index.cjs +26 -149
- package/dist/query/index.d.cts +5 -3
- package/dist/query/index.d.ts +6 -3
- package/dist/query/index.js +8 -137
- package/dist/queryBuilder-DM6AWCBa.js +820 -0
- package/dist/queryBuilder-DM6AWCBa.js.map +1 -0
- package/dist/queryBuilder-DbUMEZln.cjs +944 -0
- package/dist/selection-C4UhsMOO.d.ts +434 -0
- package/dist/selection-C4UhsMOO.d.ts.map +1 -0
- package/dist/selection-DPg0uyJf.d.cts +433 -0
- package/dist/selection-DPg0uyJf.d.cts.map +1 -0
- package/dist/types/index.cjs +4 -1
- package/dist/types/index.d.cts +7 -2
- package/dist/types/index.d.ts +8 -2
- package/dist/types/index.js +4 -1
- package/dist/types-Bu_ZwMbZ.js +0 -0
- package/dist/types-NRqymi6S.cjs +0 -0
- package/dist/utils/index.cjs +4 -17
- package/dist/utils/index.d.cts +3 -17
- package/dist/utils/index.d.ts +3 -17
- package/dist/utils/index.js +4 -18
- package/package.json +26 -5
- package/src/actions/advanced/advanced.test.ts +258 -0
- package/src/actions/advanced/buildMutation.ts +104 -0
- package/src/actions/advanced/getMutationResult.ts +112 -0
- package/src/actions/advanced/index.ts +21 -0
- package/src/actions/advanced/pingTransaction.ts +43 -0
- package/src/actions/advanced/sendMutation.ts +59 -0
- package/src/actions/public/getEntity.ts +27 -43
- package/src/actions/public/getEntityNonce.ts +30 -0
- package/src/actions/public/predictEntityKeys.test.ts +143 -0
- package/src/actions/public/predictEntityKeys.ts +138 -0
- package/src/actions/public/query.ts +35 -67
- package/src/actions/public/watchEntityEvents.test.ts +414 -0
- package/src/actions/public/watchEntityEvents.ts +225 -0
- package/src/actions/wallet/changeOwnership.ts +8 -8
- package/src/actions/wallet/createEntity.ts +104 -26
- package/src/actions/wallet/deleteEntity.ts +2 -3
- package/src/actions/wallet/extendEntity.ts +39 -16
- package/src/actions/wallet/mutateEntities.test.ts +76 -0
- package/src/actions/wallet/mutateEntities.ts +23 -83
- package/src/actions/wallet/patchEntity.ts +90 -0
- package/src/attr/attributes.test.ts +120 -0
- package/src/attr/attributes.ts +190 -0
- package/src/attr/codec.test.ts +162 -0
- package/src/attr/codec.ts +220 -0
- package/src/attr/decimal.ts +86 -0
- package/src/attr/errors.ts +145 -0
- package/src/attr/index.ts +50 -0
- package/src/attr/names.ts +106 -0
- package/src/attr/types.ts +150 -0
- package/src/attr/values.test.ts +271 -0
- package/src/attr/values.ts +502 -0
- package/src/chains/cheesecake.ts +22 -0
- package/src/chains/index.ts +1 -2
- package/src/clients/createPublicClient.test.ts +3 -5
- package/src/clients/createPublicClient.ts +5 -4
- package/src/clients/createWalletClient.test.ts +2 -2
- package/src/clients/createWalletClient.ts +13 -7
- package/src/clients/decorators/arkivAdvanced.ts +144 -0
- package/src/clients/decorators/arkivPublic.ts +172 -139
- package/src/clients/decorators/arkivWallet.ts +106 -95
- package/src/consts.ts +2 -1
- package/src/entity/create.test.ts +184 -0
- package/src/entity/errors.ts +38 -0
- package/src/entity/events.ts +16 -0
- package/src/entity/expiry.test.ts +195 -0
- package/src/entity/expiry.ts +181 -0
- package/src/entity/flags.ts +65 -0
- package/src/entity/index.ts +15 -0
- package/src/entity/key.ts +68 -0
- package/src/entity/operations.ts +134 -0
- package/src/entity/params.ts +15 -0
- package/src/errors.ts +33 -28
- package/src/index.ts +19 -0
- package/src/query/engine.ts +68 -132
- package/src/query/errors.ts +151 -0
- package/src/query/expression.test.ts +286 -0
- package/src/query/expression.ts +493 -0
- package/src/query/index.ts +40 -4
- package/src/query/injection.test.ts +151 -0
- package/src/query/queryBuilder.test.ts +342 -637
- package/src/query/queryBuilder.ts +133 -359
- package/src/query/queryResult.ts +54 -51
- package/src/query/selection.test.ts +48 -98
- package/src/query/selection.ts +77 -65
- package/src/types/entity.test.ts +44 -155
- package/src/types/entity.ts +62 -44
- package/src/types/events.ts +64 -23
- package/src/types/index.ts +20 -16
- package/src/types/rpcSchema.ts +70 -33
- package/src/utils/arkivTransactions.test.ts +681 -38
- package/src/utils/arkivTransactions.ts +400 -115
- package/src/utils/chains.test.ts +21 -24
- package/src/utils/compression.ts +1 -1
- package/src/utils/entities.test.ts +62 -0
- package/src/utils/entities.ts +111 -29
- package/src/utils/expirationTime.ts +114 -10
- package/src/utils/logger.ts +2 -2
- package/src/utils/payload.ts +4 -2
- package/src/utils/revert.test.ts +99 -0
- package/src/utils/revert.ts +145 -0
- package/dist/chains-BifaY04V.cjs +0 -108
- package/dist/chains-CrtkVbBh.js +0 -86
- package/dist/chains-CrtkVbBh.js.map +0 -1
- package/dist/consts-AUoL-v42.cjs +0 -18
- package/dist/consts-BV4PR-de.js +0 -7
- package/dist/consts-BV4PR-de.js.map +0 -1
- package/dist/entity-B6g_EPm1.d.cts +0 -382
- package/dist/entity-B6g_EPm1.d.cts.map +0 -1
- package/dist/entity-qoLMAuuk.d.ts +0 -382
- package/dist/entity-qoLMAuuk.d.ts.map +0 -1
- package/dist/index-DdspxNAA.d.ts +0 -481
- package/dist/index-DdspxNAA.d.ts.map +0 -1
- package/dist/index-Ds9dwqb5.d.cts +0 -481
- package/dist/index-Ds9dwqb5.d.cts.map +0 -1
- package/dist/payload-B2kFJyah.d.ts +0 -6
- package/dist/payload-B2kFJyah.d.ts.map +0 -1
- package/dist/payload-CJN8fTvX.d.cts +0 -6
- package/dist/payload-CJN8fTvX.d.cts.map +0 -1
- package/dist/payload-Claf2jUO.js +0 -13
- package/dist/payload-Claf2jUO.js.map +0 -1
- package/dist/payload-DpA5PA-w.cjs +0 -23
- package/dist/query/index.js.map +0 -1
- package/dist/queryBuilder-D2uwP9jI.js +0 -704
- package/dist/queryBuilder-D2uwP9jI.js.map +0 -1
- package/dist/queryBuilder-UW2MCaX4.cjs +0 -792
- package/dist/utils/index.d.cts.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/src/actions/public/buildQuery.ts +0 -10
- package/src/actions/public/subscribeEntityEvents.ts +0 -119
- package/src/actions/wallet/updateEntity.ts +0 -60
- package/src/chains/braga.ts +0 -26
- package/src/chains/kaolin.ts +0 -29
- package/src/query/engine.test.ts +0 -526
- package/src/query/predicate.test.ts +0 -461
- package/src/query/predicate.ts +0 -144
- package/src/query/queryResult.test.ts +0 -270
- package/src/query/selectQueryBuilder.test.ts +0 -210
- package/src/types/attributes.ts +0 -16
- package/src/utils/validation.test.ts +0 -60
- package/src/utils/validation.ts +0 -32
- /package/dist/{types-H-TSmRpm.js → attr-DlmErkvR.cjs} +0 -0
- /package/dist/{types-o3zWarRp.cjs → attr-GcQKatub.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
|
-
import { t as chains_exports } from "./chains-
|
|
2
|
-
import {
|
|
3
|
-
import { n as
|
|
4
|
-
import "./
|
|
5
|
-
import { n as
|
|
6
|
-
import {
|
|
1
|
+
import { t as chains_exports } from "./chains-BJrZs6sG.js";
|
|
2
|
+
import { a as OperationType, i as MAX_EXPIRES_AT, n as resolveExpiry, o as ARKIV_ADDRESS, r as toBlocks, s as BLOCK_TIME } from "./expiry-BjpxZZQU.js";
|
|
3
|
+
import { a as buildMutation, c as mutationNeedsBlockNumber, i as getMutationResult, l as sendArkivTransaction, n as pingTransaction, o as buildEntityOperations, r as decodeMutationResult, s as collectMutationEvents, t as sendMutation, u as ENTITY_NONCE_ABI } from "./advanced-8ZPTmmaN.js";
|
|
4
|
+
import { A as DECIMAL_UNIT, C as str, E as u64, F as TooManyAttributesError, I as UnknownAttributeTypeError, L as UntypedValueError, M as InvalidAttributeNameError, N as InvalidValueError, O as isArkivValue, P as MissingValueError, S as key, T as u256, _ as bytes32, a as MAX_NAME_BYTES, b as decUnits, d as I32_MIN, f as MAX_STRING_BYTES, g as bool, h as addr, j as ConflictingMutationError, k as DECIMAL_SCALE, m as U64_MAX, n as MAX_PAYLOAD_BYTES, o as isValidAttributeName, p as U256_MAX, s as validateAttributeName, t as MAX_ATTRIBUTES, u as I32_MAX, v as dec, w as toValue, x as i32, y as decFromUnits } from "./attributes-BhY5DwJp.js";
|
|
5
|
+
import { a as ENTITY_EVENTS_ABI, i as validateSalt, n as predictEntityKey, r as randomSalt, t as MAX_SALT } from "./key-D1Bh7MF0.js";
|
|
6
|
+
import { i as NoRandomSourceError, n as InvalidExpiryError, r as InvalidSaltError, t as InvalidCreationFlagsError } from "./errors-LTe7bOYS.js";
|
|
7
|
+
import { n as encodeCreationFlags, t as decodeCreationFlags } from "./flags-DFBs2J94.js";
|
|
8
|
+
import { a as NoEntityFoundError, i as InvalidContentTypeError, n as EmptyPatchError, o as NoMoreResultsError, r as EntityMutationError, t as getLogger } from "./logger-CVpvU8ik.js";
|
|
9
|
+
import "./attr-GcQKatub.js";
|
|
10
|
+
import { t as Entity } from "./entity-BYQR1uoe.js";
|
|
11
|
+
import { a as eq, r as toRpcSelect, t as SelectQueryBuilder, v as runQuery } from "./queryBuilder-DM6AWCBa.js";
|
|
12
|
+
import "./entity-CD_qFF2M.js";
|
|
13
|
+
import "./types-Bu_ZwMbZ.js";
|
|
14
|
+
import { n as stringToPayload, r as ExpirationTime, t as jsonToPayload } from "./payload-Bz6651ax.js";
|
|
15
|
+
import { createClient, decodeEventLog, publicActions, walletActions } from "viem";
|
|
16
|
+
import { getChainId, readContract } from "viem/actions";
|
|
7
17
|
|
|
8
18
|
//#region src/actions/public/getBlockTiming.ts
|
|
9
|
-
const logger$
|
|
19
|
+
const logger$8 = getLogger("actions:public:get-block-timing");
|
|
10
20
|
async function getBlockTiming(client) {
|
|
11
21
|
const blockTiming = await client.request({
|
|
12
22
|
method: "arkiv_getBlockTiming",
|
|
13
23
|
params: []
|
|
14
24
|
});
|
|
15
|
-
logger$
|
|
25
|
+
logger$8("Block timing %o", blockTiming);
|
|
16
26
|
return {
|
|
17
27
|
currentBlock: BigInt(blockTiming.current_block),
|
|
18
28
|
currentBlockTime: blockTiming.current_block_time,
|
|
@@ -22,33 +32,26 @@ async function getBlockTiming(client) {
|
|
|
22
32
|
|
|
23
33
|
//#endregion
|
|
24
34
|
//#region src/actions/public/getEntity.ts
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
expiration: true,
|
|
42
|
-
owner: true,
|
|
43
|
-
creator: true,
|
|
44
|
-
createdAtBlock: true,
|
|
45
|
-
lastModifiedAtBlock: true,
|
|
46
|
-
transactionIndexInBlock: true,
|
|
47
|
-
operationIndexInTransaction: true
|
|
48
|
-
} }]
|
|
35
|
+
/**
|
|
36
|
+
* Reads one entity by key, with every field selected.
|
|
37
|
+
*
|
|
38
|
+
* Returns a {@link FullEntity} rather than an {@link Entity}: the selection is fixed at `"*"`, so
|
|
39
|
+
* every field is populated and none of them needs a `?` at the call site. The bare `Entity` type
|
|
40
|
+
* has every field optional because a `select()` result carries only what it asked for.
|
|
41
|
+
*
|
|
42
|
+
* @throws {InvalidValueError} If the key is not 32 bytes.
|
|
43
|
+
* @throws {NoEntityFoundError} If no live entity has that key — it never existed, or it was
|
|
44
|
+
* deleted or has expired.
|
|
45
|
+
*/
|
|
46
|
+
async function getEntity(client, entityKey) {
|
|
47
|
+
const { entities } = await runQuery(client, {
|
|
48
|
+
query: eq("$key", key(entityKey)).toString(),
|
|
49
|
+
select: toRpcSelect("*"),
|
|
50
|
+
limit: 1
|
|
49
51
|
});
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
const entity = entities[0];
|
|
53
|
+
if (entity === void 0) throw new NoEntityFoundError(entityKey);
|
|
54
|
+
return entity;
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
//#endregion
|
|
@@ -60,145 +63,295 @@ async function getEntityCount(client) {
|
|
|
60
63
|
});
|
|
61
64
|
}
|
|
62
65
|
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/actions/public/getEntityNonce.ts
|
|
68
|
+
const logger$7 = getLogger("actions:public:get-entity-nonce");
|
|
69
|
+
/**
|
|
70
|
+
* Reads an owner's entity-minting nonce — how many entities that account has created.
|
|
71
|
+
*
|
|
72
|
+
* This is not the account's transaction nonce. The engine keeps a separate counter per creator and
|
|
73
|
+
* mixes it into every key it mints, which is what makes two identical creates from one account land
|
|
74
|
+
* on different keys.
|
|
75
|
+
*
|
|
76
|
+
* @param owner - The account whose nonce to read.
|
|
77
|
+
* @returns The number of entities `owner` has created so far, which is the nonce its next create
|
|
78
|
+
* will use.
|
|
79
|
+
*/
|
|
80
|
+
async function getEntityNonce(client, owner) {
|
|
81
|
+
const nonce = await readContract(client, {
|
|
82
|
+
address: ARKIV_ADDRESS,
|
|
83
|
+
abi: ENTITY_NONCE_ABI,
|
|
84
|
+
functionName: "entityNonce",
|
|
85
|
+
args: [owner]
|
|
86
|
+
});
|
|
87
|
+
logger$7("entity nonce of %s is %s", owner, nonce);
|
|
88
|
+
return nonce;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/actions/public/predictEntityKeys.ts
|
|
93
|
+
/**
|
|
94
|
+
* Works out the keys an account's next creates will be given, before sending them.
|
|
95
|
+
*
|
|
96
|
+
* A key is `keccak256(chainId ++ registry ++ owner ++ nonce ++ salt)`. Everything but the nonce is
|
|
97
|
+
* known to the caller, and the nonce is read here — so a batch can reference a key it is about to
|
|
98
|
+
* mint, storing it as a `key` attribute on a sibling entity created in the same transaction.
|
|
99
|
+
*
|
|
100
|
+
* Each key arrives paired with its salt, and the create must be given that salt: a create left to
|
|
101
|
+
* pick its own salt picks a random one, which mints a different key.
|
|
102
|
+
*
|
|
103
|
+
* The prediction is valid only while nothing else from this owner is in flight. Every create that
|
|
104
|
+
* lands first takes the nonce with it and moves these keys. For a key you can rely on
|
|
105
|
+
* unconditionally, read it back from the create instead — `createEntity` and `mutateEntities`
|
|
106
|
+
* report the keys the engine actually minted.
|
|
107
|
+
*
|
|
108
|
+
* @param parameters - Owner, and either a count or the salts. {@link PredictEntityKeysParameters}
|
|
109
|
+
* @returns One `{ key, salt }` pair per create, in batch order. {@link PredictEntityKeysReturnType}
|
|
110
|
+
*
|
|
111
|
+
* @example A batch whose second entity points at its first.
|
|
112
|
+
* import { key } from "@arkiv-network/sdk/attr"
|
|
113
|
+
*
|
|
114
|
+
* const [parent, child] = await client.predictEntityKeys({ owner: account.address, count: 2 })
|
|
115
|
+
* await wallet.mutateEntities({
|
|
116
|
+
* creates: [
|
|
117
|
+
* { payload, contentType, expires, salt: parent.salt },
|
|
118
|
+
* {
|
|
119
|
+
* payload,
|
|
120
|
+
* contentType,
|
|
121
|
+
* expires,
|
|
122
|
+
* salt: child.salt,
|
|
123
|
+
* attributes: { parent: key(parent.key) },
|
|
124
|
+
* },
|
|
125
|
+
* ],
|
|
126
|
+
* })
|
|
127
|
+
*/
|
|
128
|
+
async function predictEntityKeys(client, { owner, count, salts }) {
|
|
129
|
+
const resolvedSalts = resolveSalts(count, salts);
|
|
130
|
+
const chainId = client.chain?.id ?? await getChainId(client);
|
|
131
|
+
const nonce = await getEntityNonce(client, owner);
|
|
132
|
+
return resolvedSalts.map((salt, index) => ({
|
|
133
|
+
key: predictEntityKey({
|
|
134
|
+
owner,
|
|
135
|
+
nonce: nonce + BigInt(index),
|
|
136
|
+
salt,
|
|
137
|
+
chainId
|
|
138
|
+
}),
|
|
139
|
+
salt
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
/** The salts to derive from: the ones given, or `count` fresh random ones. */
|
|
143
|
+
function resolveSalts(count, salts) {
|
|
144
|
+
if (salts !== void 0) {
|
|
145
|
+
if (salts.length === 0) throw new Error("predictEntityKeys: `salts` is empty — there is nothing to predict");
|
|
146
|
+
return salts.map(validateSalt);
|
|
147
|
+
}
|
|
148
|
+
if (count === void 0) throw new Error("predictEntityKeys: pass either `count` or `salts`");
|
|
149
|
+
if (!Number.isInteger(count) || count <= 0) throw new Error(`predictEntityKeys: \`count\` must be a positive whole number, got ${count}`);
|
|
150
|
+
return Array.from({ length: count }, () => randomSalt());
|
|
151
|
+
}
|
|
152
|
+
|
|
63
153
|
//#endregion
|
|
64
154
|
//#region src/actions/public/query.ts
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
...queryOptions?.orderBy && { orderBy: queryOptions?.orderBy.map((order) => ({
|
|
82
|
-
name: order.name,
|
|
83
|
-
type: order.type,
|
|
84
|
-
desc: order.desc === "desc"
|
|
85
|
-
})) },
|
|
86
|
-
...queryOptions?.resultsPerPage !== void 0 && { resultsPerPage: numberToHex(queryOptions.resultsPerPage) },
|
|
87
|
-
...queryOptions?.cursor !== void 0 && { cursor: queryOptions?.cursor }
|
|
88
|
-
};
|
|
89
|
-
const result = await client.request({
|
|
90
|
-
method: "arkiv_query",
|
|
91
|
-
params: [query$1, rpcQueryOptions]
|
|
155
|
+
/**
|
|
156
|
+
* Runs a single query and returns one page, with no builder in between.
|
|
157
|
+
*
|
|
158
|
+
* Takes either an {@link Expression} or a raw query string. The string form is an escape hatch for
|
|
159
|
+
* a query built elsewhere — it goes to the node exactly as written, with none of the name, type or
|
|
160
|
+
* operator checks the expression combinators apply.
|
|
161
|
+
*
|
|
162
|
+
* @throws {QueryError} If the node rejects the query.
|
|
163
|
+
*/
|
|
164
|
+
function query(client, query$1, options = {}) {
|
|
165
|
+
return runQuery(client, {
|
|
166
|
+
query: query$1.toString(),
|
|
167
|
+
select: toRpcSelect(options.select),
|
|
168
|
+
limit: options.limit,
|
|
169
|
+
cursor: options.cursor,
|
|
170
|
+
atBlock: options.atBlock
|
|
92
171
|
});
|
|
93
|
-
return {
|
|
94
|
-
entities: await Promise.all(result.data.map((entity) => entityFromRpcResult(entity))),
|
|
95
|
-
cursor: result.cursor,
|
|
96
|
-
blockNumber: BigInt(result.blockNumber)
|
|
97
|
-
};
|
|
98
172
|
}
|
|
99
173
|
|
|
100
174
|
//#endregion
|
|
101
|
-
//#region src/actions/public/
|
|
102
|
-
const logger$
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
175
|
+
//#region src/actions/public/watchEntityEvents.ts
|
|
176
|
+
const logger$6 = getLogger("actions:public:watch-entity-events");
|
|
177
|
+
/**
|
|
178
|
+
* How often to poll, when the caller does not say.
|
|
179
|
+
*
|
|
180
|
+
* Half a block: fast enough that an event is never a whole block stale, slow enough not to hammer
|
|
181
|
+
* the node. viem's own default is derived from a 12-second Ethereum block and is far too slow here.
|
|
182
|
+
*/
|
|
183
|
+
const DEFAULT_POLLING_INTERVAL = BLOCK_TIME * 1e3 / 2;
|
|
184
|
+
/**
|
|
185
|
+
* Watches entity events, calling the handlers you pass as they arrive.
|
|
186
|
+
*
|
|
187
|
+
* Every event here is decoded from a log the Arkiv operation address emitted, and carries the
|
|
188
|
+
* block, transaction and log index it came from — so consuming them in order replays exactly what
|
|
189
|
+
* the engine did.
|
|
190
|
+
*
|
|
191
|
+
* @param parameters - Handlers and options. {@link WatchEntityEventsParameters}
|
|
192
|
+
* @returns A function that stops the watcher.
|
|
193
|
+
*
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* import { createPublicClient } from "@arkiv-network/sdk"
|
|
197
|
+
* import { cheesecake } from "@arkiv-network/sdk/chains"
|
|
198
|
+
* import { http } from "viem"
|
|
199
|
+
*
|
|
200
|
+
* const client = createPublicClient({ chain: cheesecake, transport: http() })
|
|
201
|
+
*
|
|
202
|
+
* const unwatch = client.watchEntityEvents({
|
|
203
|
+
* onEntityCreated: ({ entityKey, owner, expiresAt }) =>
|
|
204
|
+
* console.log("created", entityKey, "by", owner, "until block", expiresAt),
|
|
205
|
+
* onEntityDeleted: ({ entityKey }) => console.log("deleted", entityKey),
|
|
206
|
+
* onError: (error) => console.error(error),
|
|
207
|
+
* })
|
|
208
|
+
*
|
|
209
|
+
* unwatch()
|
|
210
|
+
*/
|
|
211
|
+
function watchEntityEvents(client, parameters) {
|
|
212
|
+
const { onEntityCreated, onEntityPatched, onExpiryExtended, onOwnershipTransferred, onEntityDeleted, onEvent, onError, fromBlock, pollingInterval = DEFAULT_POLLING_INTERVAL } = parameters;
|
|
213
|
+
const publicClient = client;
|
|
214
|
+
const reportError = onError ?? logToConsole;
|
|
215
|
+
function emit(event) {
|
|
216
|
+
deliver(onEvent, event);
|
|
217
|
+
switch (event.type) {
|
|
218
|
+
case "EntityCreated":
|
|
219
|
+
deliver(onEntityCreated, event);
|
|
220
|
+
break;
|
|
221
|
+
case "EntityPatched":
|
|
222
|
+
deliver(onEntityPatched, event);
|
|
223
|
+
break;
|
|
224
|
+
case "ExpiryExtended":
|
|
225
|
+
deliver(onExpiryExtended, event);
|
|
226
|
+
break;
|
|
227
|
+
case "OwnershipTransferred":
|
|
228
|
+
deliver(onOwnershipTransferred, event);
|
|
229
|
+
break;
|
|
230
|
+
case "EntityDeleted":
|
|
231
|
+
deliver(onEntityDeleted, event);
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Runs one handler, keeping its failure to itself.
|
|
237
|
+
*
|
|
238
|
+
* A handler that throws is the consumer's problem, not the watcher's: letting it escape would
|
|
239
|
+
* reject the poll, drop the rest of the batch, and take down every other handler with it.
|
|
240
|
+
*/
|
|
241
|
+
function deliver(handler, event) {
|
|
242
|
+
if (handler === void 0) return;
|
|
243
|
+
try {
|
|
244
|
+
handler(event);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
reportError(asError(error));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return publicClient.watchEvent({
|
|
250
|
+
address: ARKIV_ADDRESS,
|
|
251
|
+
events: ENTITY_EVENTS_ABI,
|
|
252
|
+
pollingInterval,
|
|
253
|
+
...fromBlock !== void 0 && { fromBlock },
|
|
116
254
|
onLogs: (logs) => {
|
|
117
|
-
logger$
|
|
255
|
+
logger$6("logs %o", logs);
|
|
118
256
|
for (const log of logs) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
cost: event.args.cost
|
|
132
|
-
});
|
|
133
|
-
break;
|
|
134
|
-
case "ArkivEntityUpdated":
|
|
135
|
-
onEntityUpdated?.({
|
|
136
|
-
entityKey: toHex(event.args.entityKey, { size: 32 }),
|
|
137
|
-
owner: event.args.ownerAddress,
|
|
138
|
-
oldExpirationBlock: Number(event.args.oldExpirationBlock),
|
|
139
|
-
newExpirationBlock: Number(event.args.newExpirationBlock),
|
|
140
|
-
cost: event.args.cost
|
|
141
|
-
});
|
|
142
|
-
break;
|
|
143
|
-
case "ArkivEntityDeleted":
|
|
144
|
-
onEntityDeleted?.({
|
|
145
|
-
entityKey: toHex(event.args.entityKey, { size: 32 }),
|
|
146
|
-
owner: event.args.ownerAddress
|
|
147
|
-
});
|
|
148
|
-
break;
|
|
149
|
-
case "ArkivEntityBTLExtended":
|
|
150
|
-
onEntityExpiresInExtended?.({
|
|
151
|
-
entityKey: toHex(event.args.entityKey, { size: 32 }),
|
|
152
|
-
owner: event.args.ownerAddress,
|
|
153
|
-
oldExpirationBlock: Number(event.args.oldExpirationBlock),
|
|
154
|
-
newExpirationBlock: Number(event.args.newExpirationBlock),
|
|
155
|
-
cost: event.args.cost
|
|
156
|
-
});
|
|
157
|
-
break;
|
|
158
|
-
case "ArkivEntityExpired":
|
|
159
|
-
onEntityExpired?.({
|
|
160
|
-
entityKey: toHex(event.args.entityKey, { size: 32 }),
|
|
161
|
-
owner: event.args.ownerAddress
|
|
162
|
-
});
|
|
163
|
-
break;
|
|
164
|
-
case "ArkivEntityOwnerChanged":
|
|
165
|
-
onEntityOwnerChanged?.({
|
|
166
|
-
entityKey: toHex(event.args.entityKey, { size: 32 }),
|
|
167
|
-
oldOwner: event.args.oldOwnerAddress,
|
|
168
|
-
newOwner: event.args.newOwnerAddress
|
|
169
|
-
});
|
|
170
|
-
break;
|
|
171
|
-
default:
|
|
172
|
-
console.warn("unknown event from subscribeEntityEvents", event);
|
|
173
|
-
break;
|
|
257
|
+
if (log.blockNumber === null || log.transactionHash === null || log.logIndex === null) continue;
|
|
258
|
+
const context = {
|
|
259
|
+
blockNumber: log.blockNumber,
|
|
260
|
+
transactionHash: log.transactionHash,
|
|
261
|
+
logIndex: log.logIndex
|
|
262
|
+
};
|
|
263
|
+
let event;
|
|
264
|
+
try {
|
|
265
|
+
event = toEntityEvent(log.topics, log.data, context);
|
|
266
|
+
} catch (error) {
|
|
267
|
+
reportError(asError(error));
|
|
268
|
+
continue;
|
|
174
269
|
}
|
|
270
|
+
emit(event);
|
|
175
271
|
}
|
|
176
272
|
},
|
|
177
|
-
onError: (error) =>
|
|
178
|
-
console.error("error from subscribeEntityEvents", error);
|
|
179
|
-
onError?.(error);
|
|
180
|
-
}
|
|
273
|
+
onError: (error) => reportError(error)
|
|
181
274
|
});
|
|
182
275
|
}
|
|
276
|
+
/** The fallback when no `onError` was given — see {@link WatchEntityEventsParameters.onError}. */
|
|
277
|
+
function logToConsole(error) {
|
|
278
|
+
console.error("watchEntityEvents error", error);
|
|
279
|
+
}
|
|
280
|
+
/** Handlers take an `Error`, and a `throw` can be anything. */
|
|
281
|
+
function asError(error) {
|
|
282
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Decodes one log into the {@link EntityEvent} it carries.
|
|
286
|
+
*
|
|
287
|
+
* @throws If the log does not decode against {@link ENTITY_EVENTS_ABI}.
|
|
288
|
+
*/
|
|
289
|
+
function toEntityEvent(topics, data, context) {
|
|
290
|
+
const decoded = decodeEventLog({
|
|
291
|
+
abi: ENTITY_EVENTS_ABI,
|
|
292
|
+
topics,
|
|
293
|
+
data
|
|
294
|
+
});
|
|
295
|
+
switch (decoded.eventName) {
|
|
296
|
+
case "EntityCreated": return {
|
|
297
|
+
type: "EntityCreated",
|
|
298
|
+
...context,
|
|
299
|
+
...decoded.args,
|
|
300
|
+
creationFlags: decodeCreationFlags(decoded.args.creationFlags)
|
|
301
|
+
};
|
|
302
|
+
case "EntityPatched": return {
|
|
303
|
+
type: "EntityPatched",
|
|
304
|
+
...context,
|
|
305
|
+
...decoded.args
|
|
306
|
+
};
|
|
307
|
+
case "ExpiryExtended": return {
|
|
308
|
+
type: "ExpiryExtended",
|
|
309
|
+
...context,
|
|
310
|
+
...decoded.args
|
|
311
|
+
};
|
|
312
|
+
case "OwnershipTransferred": return {
|
|
313
|
+
type: "OwnershipTransferred",
|
|
314
|
+
...context,
|
|
315
|
+
...decoded.args
|
|
316
|
+
};
|
|
317
|
+
case "EntityDeleted": return {
|
|
318
|
+
type: "EntityDeleted",
|
|
319
|
+
...context,
|
|
320
|
+
...decoded.args
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
//#endregion
|
|
326
|
+
//#region src/clients/decorators/arkivAdvanced.ts
|
|
327
|
+
function publicAdvancedActions(client) {
|
|
328
|
+
return {
|
|
329
|
+
pingTransaction: (txHash) => pingTransaction(client, txHash),
|
|
330
|
+
getMutationResult: (txHash) => getMutationResult(client, txHash),
|
|
331
|
+
decodeMutationResult: (receipt) => decodeMutationResult(receipt)
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
function walletAdvancedActions(client) {
|
|
335
|
+
return {
|
|
336
|
+
...publicAdvancedActions(client),
|
|
337
|
+
buildMutation: (data, options) => buildMutation(client, data, options),
|
|
338
|
+
sendMutation: (data, options) => sendMutation(client, data, options)
|
|
339
|
+
};
|
|
340
|
+
}
|
|
183
341
|
|
|
184
342
|
//#endregion
|
|
185
343
|
//#region src/clients/decorators/arkivPublic.ts
|
|
186
344
|
function publicArkivActions(client) {
|
|
187
345
|
return {
|
|
188
|
-
getEntity: (key) => getEntity(client, key),
|
|
346
|
+
getEntity: (key$1) => getEntity(client, key$1),
|
|
189
347
|
query: (rawQuery, queryOptions) => query(client, rawQuery, queryOptions),
|
|
190
|
-
buildQuery: () => new QueryBuilder(client),
|
|
191
348
|
select: (selection) => new SelectQueryBuilder(client, selection),
|
|
192
349
|
getBlockTiming: () => getBlockTiming(client),
|
|
193
350
|
getEntityCount: () => getEntityCount(client),
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
onEntityDeleted,
|
|
199
|
-
onEntityExpired,
|
|
200
|
-
onEntityExpiresInExtended
|
|
201
|
-
}, pollingInterval, fromBlock)
|
|
351
|
+
getEntityNonce: (owner) => getEntityNonce(client, owner),
|
|
352
|
+
predictEntityKeys: (parameters) => predictEntityKeys(client, parameters),
|
|
353
|
+
watchEntityEvents: (parameters) => watchEntityEvents(client, parameters),
|
|
354
|
+
advanced: publicAdvancedActions(client)
|
|
202
355
|
};
|
|
203
356
|
}
|
|
204
357
|
|
|
@@ -209,201 +362,36 @@ function publicArkivActions(client) {
|
|
|
209
362
|
*
|
|
210
363
|
* - Docs: https://docs.arkiv.network/ts-sdk/clients/public
|
|
211
364
|
*
|
|
212
|
-
* A Public Client is an interface to "public" [Ethereum JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/), [Arkiv JSON-RPC API](https://docs.arkiv.network/json-rpc/), and [
|
|
365
|
+
* A Public Client is an interface to "public" [Ethereum JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/), [Arkiv JSON-RPC API](https://docs.arkiv.network/json-rpc/), and [Cheesecake JSON-RPC API](https://rpc.cheesecake.db-chain.devnet.gobas.me) methods such as retrieving block numbers, transactions, reading from smart contracts, etc through [Public Actions](/docs/actions/public/introduction).
|
|
213
366
|
*
|
|
214
367
|
* @param parameters - Configuration object for the public client (chain, transport, etc.)
|
|
215
368
|
* @returns A Arkiv Public Client. {@link PublicArkivClient}
|
|
216
369
|
*
|
|
217
370
|
* @example
|
|
218
|
-
* import { createPublicClient
|
|
219
|
-
* import {
|
|
371
|
+
* import { createPublicClient } from "@arkiv-network/sdk"
|
|
372
|
+
* import { cheesecake } from "@arkiv-network/sdk/chains"
|
|
373
|
+
* import { http } from "viem"
|
|
220
374
|
*
|
|
221
375
|
* const client = createPublicClient({
|
|
222
|
-
* chain:
|
|
376
|
+
* chain: cheesecake,
|
|
223
377
|
* transport: http(),
|
|
224
378
|
* })
|
|
225
379
|
*/
|
|
226
380
|
function createPublicClient(parameters) {
|
|
227
|
-
const { key = "public", name = "Public Client" } = parameters;
|
|
381
|
+
const { key: key$1 = "public", name = "Public Client" } = parameters;
|
|
228
382
|
return createClient({
|
|
229
383
|
...parameters,
|
|
230
|
-
key,
|
|
384
|
+
key: key$1,
|
|
231
385
|
name
|
|
232
386
|
}).extend(publicActions).extend(publicArkivActions);
|
|
233
387
|
}
|
|
234
388
|
|
|
235
|
-
//#endregion
|
|
236
|
-
//#region src/utils/compression.ts
|
|
237
|
-
const logger$7 = getLogger("utils:compression");
|
|
238
|
-
const isNode = typeof process !== "undefined" && process.versions?.node != null;
|
|
239
|
-
let zlib = null;
|
|
240
|
-
let brotli = null;
|
|
241
|
-
async function getZlib() {
|
|
242
|
-
if (!isNode) return null;
|
|
243
|
-
if (!zlib) try {
|
|
244
|
-
zlib = await import("zlib");
|
|
245
|
-
} catch (error) {
|
|
246
|
-
console.error("Error importing zlib", error);
|
|
247
|
-
return null;
|
|
248
|
-
}
|
|
249
|
-
return zlib;
|
|
250
|
-
}
|
|
251
|
-
async function getBrotli() {
|
|
252
|
-
if (brotli) return brotli;
|
|
253
|
-
try {
|
|
254
|
-
const brotliModule = await import("brotli-wasm");
|
|
255
|
-
brotli = brotliModule.default ? await brotliModule.default : brotliModule;
|
|
256
|
-
} catch (error) {
|
|
257
|
-
console.error("Error importing brotli-wasm", error);
|
|
258
|
-
return null;
|
|
259
|
-
}
|
|
260
|
-
return brotli;
|
|
261
|
-
}
|
|
262
|
-
async function compress(data) {
|
|
263
|
-
logger$7("Compressing data size %d", data.length);
|
|
264
|
-
if (isNode) {
|
|
265
|
-
const zlibModule = await getZlib();
|
|
266
|
-
if (zlibModule) try {
|
|
267
|
-
const buffer = Buffer.from(data);
|
|
268
|
-
const compressed = zlibModule.brotliCompressSync(buffer);
|
|
269
|
-
const result = new Uint8Array(compressed);
|
|
270
|
-
logger$7("Brotli compressed with zlib size %d", result.length);
|
|
271
|
-
return result;
|
|
272
|
-
} catch (error) {
|
|
273
|
-
console.warn("zlib compression failed, falling back to brotli-wasm", error);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
const brotliInstance = await getBrotli();
|
|
277
|
-
if (!brotliInstance) {
|
|
278
|
-
console.warn("Brotli instance not found, not compressing data");
|
|
279
|
-
return data;
|
|
280
|
-
}
|
|
281
|
-
const brotliCompressed = brotliInstance.compress(data);
|
|
282
|
-
logger$7("Brotli compressed with wasm size %d", brotliCompressed.length);
|
|
283
|
-
return brotliCompressed;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
//#endregion
|
|
287
|
-
//#region src/utils/validation.ts
|
|
288
|
-
/**
|
|
289
|
-
* Expiration on Arkiv is measured in blocks (1 block =
|
|
290
|
-
* 2 seconds), so the value must be a positive integer that is
|
|
291
|
-
* a multiple of the block time.
|
|
292
|
-
*
|
|
293
|
-
* @param expiresIn - The expiration in seconds.
|
|
294
|
-
* @throws {InvalidExpirationError} If the value is not a positive integer that
|
|
295
|
-
* is a multiple of the block time.
|
|
296
|
-
*/
|
|
297
|
-
function validateExpiresIn(expiresIn) {
|
|
298
|
-
if (!Number.isInteger(expiresIn) || expiresIn <= 0 || expiresIn % BLOCK_TIME !== 0) throw new InvalidExpirationError(expiresIn);
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* Validates a single attribute. Arkiv supports string and number attribute
|
|
302
|
-
* values, but numeric values must be integers.
|
|
303
|
-
*
|
|
304
|
-
* @param attribute - The attribute to validate.
|
|
305
|
-
* @throws {InvalidAttributeError} If the attribute has a non-integer numeric
|
|
306
|
-
* value.
|
|
307
|
-
*/
|
|
308
|
-
function validateAttribute(attribute) {
|
|
309
|
-
if (typeof attribute.value === "number" && !Number.isInteger(attribute.value)) throw new InvalidAttributeError(attribute.key, attribute.value);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
//#endregion
|
|
313
|
-
//#region src/utils/arkivTransactions.ts
|
|
314
|
-
const logger$6 = getLogger("utils:arkiv-transactions");
|
|
315
|
-
function opsToTxData({ creates, updates, deletes, extensions, ownershipChanges }) {
|
|
316
|
-
function formatAttributes(attribute) {
|
|
317
|
-
return [toHex(attribute.key), toHex(typeof attribute.value === "number" && attribute.value === 0 ? "" : attribute.value)];
|
|
318
|
-
}
|
|
319
|
-
const payload = [
|
|
320
|
-
(creates ?? []).map((item) => {
|
|
321
|
-
validateExpiresIn(item.expiresIn);
|
|
322
|
-
item.attributes.forEach(validateAttribute);
|
|
323
|
-
return [
|
|
324
|
-
toHex(item.expiresIn / BLOCK_TIME),
|
|
325
|
-
toHex(item.contentType),
|
|
326
|
-
toHex(item.payload),
|
|
327
|
-
item.attributes.filter((attribute) => typeof attribute.value === "string").map(formatAttributes),
|
|
328
|
-
item.attributes.filter((attribute) => typeof attribute.value === "number").map(formatAttributes)
|
|
329
|
-
];
|
|
330
|
-
}),
|
|
331
|
-
(updates ?? []).map((item) => {
|
|
332
|
-
validateExpiresIn(item.expiresIn);
|
|
333
|
-
item.attributes.forEach(validateAttribute);
|
|
334
|
-
return [
|
|
335
|
-
item.entityKey,
|
|
336
|
-
toHex(item.contentType),
|
|
337
|
-
toHex(item.expiresIn / BLOCK_TIME),
|
|
338
|
-
toHex(item.payload),
|
|
339
|
-
item.attributes.filter((attribute) => typeof attribute.value === "string").map(formatAttributes),
|
|
340
|
-
item.attributes.filter((attribute) => typeof attribute.value === "number").map(formatAttributes)
|
|
341
|
-
];
|
|
342
|
-
}),
|
|
343
|
-
(deletes ?? []).map((item) => item.entityKey),
|
|
344
|
-
(extensions ?? []).map((item) => {
|
|
345
|
-
validateExpiresIn(item.expiresIn);
|
|
346
|
-
return [item.entityKey, toHex(item.expiresIn / BLOCK_TIME)];
|
|
347
|
-
}),
|
|
348
|
-
(ownershipChanges ?? []).map((item) => [item.entityKey, item.newOwner])
|
|
349
|
-
];
|
|
350
|
-
logger$6("txData to send as RLP %o length %d", payload, payload.length);
|
|
351
|
-
return toRlp(payload);
|
|
352
|
-
}
|
|
353
|
-
async function sendArkivTransaction(client, data, txParams) {
|
|
354
|
-
if (!client.account) throw new Error("Account required");
|
|
355
|
-
const walletClient = client;
|
|
356
|
-
logger$6("Sending transaction %o", {
|
|
357
|
-
account: client.account,
|
|
358
|
-
chain: client.chain,
|
|
359
|
-
to: ARKIV_ADDRESS,
|
|
360
|
-
value: 0n,
|
|
361
|
-
data,
|
|
362
|
-
...txParams
|
|
363
|
-
});
|
|
364
|
-
try {
|
|
365
|
-
const compressed = await compress(toBytes(data));
|
|
366
|
-
const txHash = await walletClient.sendTransaction({
|
|
367
|
-
account: client.account,
|
|
368
|
-
chain: client.chain,
|
|
369
|
-
to: ARKIV_ADDRESS,
|
|
370
|
-
value: 0n,
|
|
371
|
-
data: toHex(compressed),
|
|
372
|
-
...txParams
|
|
373
|
-
});
|
|
374
|
-
const receipt = await walletClient.waitForTransactionReceipt({ hash: txHash });
|
|
375
|
-
logger$6("Tx receipt %o", receipt);
|
|
376
|
-
if (receipt.status === "reverted") try {
|
|
377
|
-
const callResult = await walletClient.call({
|
|
378
|
-
account: client.account,
|
|
379
|
-
to: ARKIV_ADDRESS,
|
|
380
|
-
value: 0n,
|
|
381
|
-
data: toHex(compressed),
|
|
382
|
-
...txParams
|
|
383
|
-
});
|
|
384
|
-
throw new EntityMutationError(`Transaction ${receipt.transactionHash} reverted. Please make sure the data for entities doesn't contain invalid characters or invalid data types.
|
|
385
|
-
Reason: ${callResult.data ? hexToString(callResult.data) : "No reason provided by backend."}`);
|
|
386
|
-
} catch (err) {
|
|
387
|
-
const reason = err.cause?.details ?? "No reason provided by backend.";
|
|
388
|
-
logger$6("Error while calling to get more details about reverted transaction. Reason: %s", reason);
|
|
389
|
-
throw new EntityMutationError(`Transaction ${receipt.transactionHash} reverted. Reason: ${reason}`);
|
|
390
|
-
}
|
|
391
|
-
return receipt;
|
|
392
|
-
} catch (error) {
|
|
393
|
-
let message = "Transaction failed";
|
|
394
|
-
if (error instanceof TransactionExecutionError) message += `: ${error.details}`;
|
|
395
|
-
else if (error instanceof EntityMutationError) throw error;
|
|
396
|
-
logger$6("%s Detailed error stack: %o", message, error);
|
|
397
|
-
throw new EntityMutationError(message);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
389
|
//#endregion
|
|
402
390
|
//#region src/actions/wallet/changeOwnership.ts
|
|
403
391
|
const logger$5 = getLogger("actions:wallet:change-ownership");
|
|
404
392
|
async function changeOwnership(client, data, txParams) {
|
|
405
393
|
logger$5("changeOwnership %o", data);
|
|
406
|
-
const receipt = await sendArkivTransaction(client,
|
|
394
|
+
const { receipt } = await sendArkivTransaction(client, { ownershipChanges: [data] }, txParams);
|
|
407
395
|
logger$5("Receipt from changeOwnership %o", receipt);
|
|
408
396
|
return {
|
|
409
397
|
txHash: receipt.transactionHash,
|
|
@@ -416,11 +404,15 @@ async function changeOwnership(client, data, txParams) {
|
|
|
416
404
|
const logger$4 = getLogger("actions:wallet:create-entity");
|
|
417
405
|
async function createEntity(client, data, txParams) {
|
|
418
406
|
logger$4("createEntity %o", data);
|
|
419
|
-
const receipt = await sendArkivTransaction(client,
|
|
407
|
+
const { receipt, createdEntityKeys, createdExpiries } = await sendArkivTransaction(client, { creates: [data] }, txParams);
|
|
420
408
|
logger$4("Receipt from createEntity %o", receipt);
|
|
409
|
+
const [entityKey] = createdEntityKeys;
|
|
410
|
+
const [expiresAt] = createdExpiries;
|
|
411
|
+
if (entityKey === void 0 || expiresAt === void 0) throw new EntityMutationError(`Transaction ${receipt.transactionHash} succeeded, but the receipt did not carry the expected entity key or expiry.`);
|
|
421
412
|
return {
|
|
422
413
|
txHash: receipt.transactionHash,
|
|
423
|
-
entityKey
|
|
414
|
+
entityKey,
|
|
415
|
+
expiresAt
|
|
424
416
|
};
|
|
425
417
|
}
|
|
426
418
|
|
|
@@ -429,7 +421,7 @@ async function createEntity(client, data, txParams) {
|
|
|
429
421
|
const logger$3 = getLogger("actions:wallet:delete-entity");
|
|
430
422
|
async function deleteEntity(client, data, txParams) {
|
|
431
423
|
logger$3("deleteEntity %o", data);
|
|
432
|
-
const receipt = await sendArkivTransaction(client,
|
|
424
|
+
const { receipt } = await sendArkivTransaction(client, { deletes: [data] }, txParams);
|
|
433
425
|
logger$3("Receipt from deleteEntity %o", receipt);
|
|
434
426
|
return {
|
|
435
427
|
txHash: receipt.transactionHash,
|
|
@@ -442,74 +434,43 @@ async function deleteEntity(client, data, txParams) {
|
|
|
442
434
|
const logger$2 = getLogger("actions:wallet:extend-entity");
|
|
443
435
|
async function extendEntity(client, data, txParams) {
|
|
444
436
|
logger$2("extendEntity %o", data);
|
|
445
|
-
const receipt = await sendArkivTransaction(client,
|
|
437
|
+
const { receipt, extendedExpiries } = await sendArkivTransaction(client, { extensions: [data] }, txParams);
|
|
446
438
|
logger$2("Receipt from extendEntity %o", receipt);
|
|
439
|
+
const [expiresAt] = extendedExpiries;
|
|
440
|
+
if (expiresAt === void 0) throw new EntityMutationError(`Transaction ${receipt.transactionHash} succeeded, but the receipt did not carry the expected entity expiry.`);
|
|
447
441
|
return {
|
|
448
442
|
txHash: receipt.transactionHash,
|
|
449
|
-
entityKey:
|
|
443
|
+
entityKey: data.entityKey,
|
|
444
|
+
expiresAt
|
|
450
445
|
};
|
|
451
446
|
}
|
|
452
447
|
|
|
453
448
|
//#endregion
|
|
454
449
|
//#region src/actions/wallet/mutateEntities.ts
|
|
455
450
|
const logger$1 = getLogger("actions:wallet:mutate-entities");
|
|
456
|
-
function parseReceipt(receipt, params) {
|
|
457
|
-
const createdEntities = [];
|
|
458
|
-
const updatedEntities = [];
|
|
459
|
-
const deletedEntities = [];
|
|
460
|
-
const extendedEntities = [];
|
|
461
|
-
const ownershipChanges = [];
|
|
462
|
-
const totalCreates = params.creates?.length ?? 0;
|
|
463
|
-
const totalUpdates = params.updates?.length ?? 0;
|
|
464
|
-
const totalDeletes = params.deletes?.length ?? 0;
|
|
465
|
-
const totalExtensions = params.extensions?.length ?? 0;
|
|
466
|
-
for (let index = 0; index < receipt.logs.length; index++) {
|
|
467
|
-
const log = receipt.logs[index];
|
|
468
|
-
if (index < totalCreates) createdEntities.push(log.topics[1]);
|
|
469
|
-
else if (index < totalCreates + totalDeletes) deletedEntities.push(log.topics[1]);
|
|
470
|
-
else if (index < totalCreates + totalUpdates + totalDeletes) updatedEntities.push(log.topics[1]);
|
|
471
|
-
else if (index < totalCreates + totalUpdates + totalDeletes + totalExtensions) extendedEntities.push(log.topics[1]);
|
|
472
|
-
else ownershipChanges.push(log.topics[1]);
|
|
473
|
-
}
|
|
474
|
-
return {
|
|
475
|
-
createdEntities,
|
|
476
|
-
updatedEntities,
|
|
477
|
-
deletedEntities,
|
|
478
|
-
extendedEntities,
|
|
479
|
-
ownershipChanges
|
|
480
|
-
};
|
|
481
|
-
}
|
|
482
451
|
async function mutateEntities(client, data, txParams) {
|
|
483
|
-
|
|
484
|
-
const receipt = await sendArkivTransaction(client, opsToTxData({
|
|
485
|
-
creates: data.creates ?? [],
|
|
486
|
-
updates: data.updates ?? [],
|
|
487
|
-
deletes: data.deletes ?? [],
|
|
488
|
-
extensions: data.extensions ?? [],
|
|
489
|
-
ownershipChanges: data.ownershipChanges ?? []
|
|
490
|
-
}), txParams);
|
|
452
|
+
const { receipt, createdEntityKeys } = await sendArkivTransaction(client, data, txParams);
|
|
491
453
|
logger$1("Receipt from mutateEntities %o", receipt);
|
|
492
|
-
const { createdEntities, updatedEntities, deletedEntities, extendedEntities, ownershipChanges } = parseReceipt(receipt, data);
|
|
493
454
|
return {
|
|
494
455
|
txHash: receipt.transactionHash,
|
|
495
|
-
createdEntities,
|
|
496
|
-
|
|
497
|
-
deletedEntities,
|
|
498
|
-
extendedEntities,
|
|
499
|
-
ownershipChanges
|
|
456
|
+
createdEntities: createdEntityKeys,
|
|
457
|
+
patchedEntities: (data.patches ?? []).map((p) => p.entityKey),
|
|
458
|
+
deletedEntities: (data.deletes ?? []).map((d) => d.entityKey),
|
|
459
|
+
extendedEntities: (data.extensions ?? []).map((e) => e.entityKey),
|
|
460
|
+
ownershipChanges: (data.ownershipChanges ?? []).map((o) => o.entityKey)
|
|
500
461
|
};
|
|
501
462
|
}
|
|
502
463
|
|
|
503
464
|
//#endregion
|
|
504
|
-
//#region src/actions/wallet/
|
|
505
|
-
const logger = getLogger("actions:wallet:
|
|
506
|
-
async function
|
|
507
|
-
logger("
|
|
508
|
-
const receipt = await sendArkivTransaction(client,
|
|
509
|
-
logger("Receipt from
|
|
465
|
+
//#region src/actions/wallet/patchEntity.ts
|
|
466
|
+
const logger = getLogger("actions:wallet:patch-entity");
|
|
467
|
+
async function patchEntity(client, data, txParams) {
|
|
468
|
+
logger("patchEntity %o", data);
|
|
469
|
+
const { receipt } = await sendArkivTransaction(client, { patches: [data] }, txParams);
|
|
470
|
+
logger("Receipt from patchEntity %o", receipt);
|
|
510
471
|
return {
|
|
511
472
|
txHash: receipt.transactionHash,
|
|
512
|
-
entityKey:
|
|
473
|
+
entityKey: data.entityKey
|
|
513
474
|
};
|
|
514
475
|
}
|
|
515
476
|
|
|
@@ -518,47 +479,54 @@ async function updateEntity(client, data, txParams) {
|
|
|
518
479
|
function walletArkivActions(client) {
|
|
519
480
|
return {
|
|
520
481
|
createEntity: (data, txParams) => createEntity(client, data, txParams),
|
|
521
|
-
|
|
482
|
+
patchEntity: (data, txParams) => patchEntity(client, data, txParams),
|
|
522
483
|
deleteEntity: (data, txParams) => deleteEntity(client, data, txParams),
|
|
523
484
|
extendEntity: (data, txParams) => extendEntity(client, data, txParams),
|
|
524
485
|
changeOwnership: (data, txParams) => changeOwnership(client, data, txParams),
|
|
525
|
-
mutateEntities: (data, txParams) => mutateEntities(client, data, txParams)
|
|
486
|
+
mutateEntities: (data, txParams) => mutateEntities(client, data, txParams),
|
|
487
|
+
advanced: walletAdvancedActions(client)
|
|
526
488
|
};
|
|
527
489
|
}
|
|
528
490
|
|
|
529
491
|
//#endregion
|
|
530
492
|
//#region src/clients/createWalletClient.ts
|
|
531
493
|
/**
|
|
532
|
-
* Creates a
|
|
494
|
+
* Creates a Wallet Client with a given [Transport](https://viem.sh/docs/clients/intro) configured
|
|
495
|
+
* for a [Chain](https://viem.sh/docs/clients/chains) and an account.
|
|
533
496
|
*
|
|
534
|
-
* - Docs: https://docs.arkiv.network/ts-sdk/clients/
|
|
497
|
+
* - Docs: https://docs.arkiv.network/ts-sdk/clients/wallet
|
|
535
498
|
*
|
|
536
|
-
* A
|
|
499
|
+
* A Wallet Client signs and sends transactions, so it carries an `account` and exposes everything
|
|
500
|
+
* that mutates state — `createEntity`, `patchEntity`, `deleteEntity`, `extendEntity`,
|
|
501
|
+
* `changeOwnership` and `mutateEntities` — on top of the read actions a Public Client has.
|
|
537
502
|
*
|
|
538
503
|
* @param parameters - Configuration object for the wallet client (chain, transport, account, etc.)
|
|
539
504
|
* @returns A Arkiv Wallet Client. {@link WalletArkivClient}
|
|
540
505
|
*
|
|
541
506
|
* @example
|
|
542
|
-
* import {
|
|
543
|
-
* import {
|
|
507
|
+
* import { createWalletClient } from "@arkiv-network/sdk"
|
|
508
|
+
* import { cheesecake } from "@arkiv-network/sdk/chains"
|
|
509
|
+
* import { http } from "viem"
|
|
510
|
+
* import { privateKeyToAccount } from "viem/accounts"
|
|
544
511
|
*
|
|
545
|
-
* const client =
|
|
546
|
-
* chain:
|
|
512
|
+
* const client = createWalletClient({
|
|
513
|
+
* chain: cheesecake,
|
|
547
514
|
* transport: http(),
|
|
515
|
+
* account: privateKeyToAccount("0x..."),
|
|
548
516
|
* })
|
|
549
517
|
*/
|
|
550
518
|
function createWalletClient(parameters) {
|
|
551
|
-
const { key = "wallet", name = "Wallet Client" } = parameters;
|
|
519
|
+
const { key: key$1 = "wallet", name = "Wallet Client" } = parameters;
|
|
552
520
|
return createClient({
|
|
553
521
|
...parameters,
|
|
554
|
-
key,
|
|
522
|
+
key: key$1,
|
|
555
523
|
name
|
|
556
524
|
}).extend(publicActions).extend(walletActions).extend(walletArkivActions);
|
|
557
525
|
}
|
|
558
526
|
|
|
559
527
|
//#endregion
|
|
560
528
|
//#region src/utils/chains.ts
|
|
561
|
-
const chainMap = new Map(Object.entries(chains_exports).map(([key, value]) => [key.toLowerCase(), value]));
|
|
529
|
+
const chainMap = new Map(Object.entries(chains_exports).map(([key$1, value]) => [key$1.toLowerCase(), value]));
|
|
562
530
|
/**
|
|
563
531
|
* Get a chain from its name
|
|
564
532
|
* @param name - The name of the chain, case insensitive
|
|
@@ -572,5 +540,5 @@ function chainFromName(name) {
|
|
|
572
540
|
}
|
|
573
541
|
|
|
574
542
|
//#endregion
|
|
575
|
-
export { EntityMutationError,
|
|
543
|
+
export { ConflictingMutationError, DECIMAL_SCALE, DECIMAL_UNIT, ENTITY_EVENTS_ABI, EmptyPatchError, Entity, EntityMutationError, ExpirationTime, I32_MAX, I32_MIN, InvalidAttributeNameError, InvalidContentTypeError, InvalidCreationFlagsError, InvalidExpiryError, InvalidSaltError, InvalidValueError, MAX_ATTRIBUTES, MAX_EXPIRES_AT, MAX_NAME_BYTES, MAX_PAYLOAD_BYTES, MAX_SALT, MAX_STRING_BYTES, MissingValueError, NoEntityFoundError, NoMoreResultsError, NoRandomSourceError, OperationType, TooManyAttributesError, U256_MAX, U64_MAX, UnknownAttributeTypeError, UntypedValueError, addr, bool, buildEntityOperations, buildMutation, bytes32, chainFromName, collectMutationEvents, createPublicClient, createWalletClient, dec, decFromUnits, decUnits, decodeCreationFlags, decodeMutationResult, encodeCreationFlags, getMutationResult, i32, isArkivValue, isValidAttributeName, jsonToPayload, key, mutationNeedsBlockNumber, pingTransaction, predictEntityKey, randomSalt, resolveExpiry, sendMutation, str, stringToPayload, toBlocks, toValue, u256, u64, validateAttributeName };
|
|
576
544
|
//# sourceMappingURL=index.js.map
|