near-kit 0.4.5 → 0.5.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.
- package/dist/core/actions.d.ts +48 -1
- package/dist/core/actions.d.ts.map +1 -1
- package/dist/core/actions.js +46 -0
- package/dist/core/actions.js.map +1 -1
- package/dist/core/rpc/rpc-schemas.d.ts +40 -0
- package/dist/core/rpc/rpc-schemas.d.ts.map +1 -1
- package/dist/core/rpc/rpc-schemas.js +7 -0
- package/dist/core/rpc/rpc-schemas.js.map +1 -1
- package/dist/core/schema.d.ts +162 -1
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +28 -0
- package/dist/core/schema.js.map +1 -1
- package/dist/core/transaction.d.ts +42 -0
- package/dist/core/transaction.d.ts.map +1 -1
- package/dist/core/transaction.js +56 -0
- package/dist/core/transaction.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/sandbox/sandbox.js +1 -1
- package/dist/sandbox/sandbox.js.map +1 -1
- package/dist/utils/index.d.ts +4 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -2
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/state-init.d.ts +134 -0
- package/dist/utils/state-init.d.ts.map +1 -0
- package/dist/utils/state-init.js +208 -0
- package/dist/utils/state-init.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NEP-616 StateInit utilities for deterministic account IDs
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities for working with NEP-616 Deterministic AccountIds.
|
|
5
|
+
* These account IDs are derived from the contract initialization state using the formula:
|
|
6
|
+
* `"0s" + hex(keccak256(borsh(state_init))[12..32])`
|
|
7
|
+
*
|
|
8
|
+
* @see https://github.com/near/NEPs/pull/616
|
|
9
|
+
*/
|
|
10
|
+
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
11
|
+
import { base58, hex } from "@scure/base";
|
|
12
|
+
import { b } from "@zorsh/zorsh";
|
|
13
|
+
// ==================== Helper Functions ====================
|
|
14
|
+
/**
|
|
15
|
+
* Parse and validate a code hash from either base58 string or Uint8Array
|
|
16
|
+
*
|
|
17
|
+
* @param codeHash - Code hash as base58 string or Uint8Array
|
|
18
|
+
* @returns Validated 32-byte hash as Uint8Array
|
|
19
|
+
* @throws Error if base58 is invalid or hash is not 32 bytes
|
|
20
|
+
*/
|
|
21
|
+
export function parseCodeHash(codeHash) {
|
|
22
|
+
let hashBytes;
|
|
23
|
+
if (typeof codeHash === "string") {
|
|
24
|
+
try {
|
|
25
|
+
hashBytes = base58.decode(codeHash);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new Error(`Invalid base58 code hash: ${codeHash}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
hashBytes = codeHash;
|
|
33
|
+
}
|
|
34
|
+
if (hashBytes.length !== 32) {
|
|
35
|
+
throw new Error(`Code hash must be 32 bytes, got ${hashBytes.length} bytes`);
|
|
36
|
+
}
|
|
37
|
+
return hashBytes;
|
|
38
|
+
}
|
|
39
|
+
// ==================== Borsh Schemas for StateInit ====================
|
|
40
|
+
/**
|
|
41
|
+
* GlobalContractIdentifier enum for Borsh serialization
|
|
42
|
+
* 0 = CodeHash (32-byte hash)
|
|
43
|
+
* 1 = AccountId (string)
|
|
44
|
+
*/
|
|
45
|
+
const GlobalContractIdentifierSchema = b.enum({
|
|
46
|
+
CodeHash: b.array(b.u8(), 32),
|
|
47
|
+
AccountId: b.string(),
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* StateInitV1 struct for Borsh serialization
|
|
51
|
+
*/
|
|
52
|
+
const StateInitV1Schema = b.struct({
|
|
53
|
+
code: GlobalContractIdentifierSchema,
|
|
54
|
+
data: b.hashMap(b.bytes(), b.bytes()),
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* StateInit enum (versioned) for Borsh serialization
|
|
58
|
+
*/
|
|
59
|
+
const StateInitSchema = b.enum({
|
|
60
|
+
V1: StateInitV1Schema,
|
|
61
|
+
});
|
|
62
|
+
/**
|
|
63
|
+
* Create a StateInit object from options
|
|
64
|
+
*
|
|
65
|
+
* @param options - StateInit configuration
|
|
66
|
+
* @returns StateInit object
|
|
67
|
+
*/
|
|
68
|
+
export function createStateInit(options) {
|
|
69
|
+
let code;
|
|
70
|
+
if ("accountId" in options.code) {
|
|
71
|
+
code = { type: "accountId", accountId: options.code.accountId };
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
const hashBytes = parseCodeHash(options.code.codeHash);
|
|
75
|
+
code = { type: "codeHash", hash: hashBytes };
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
code,
|
|
79
|
+
data: options.data ?? new Map(),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Serialize a StateInit to Borsh bytes
|
|
84
|
+
*
|
|
85
|
+
* @param stateInit - StateInit object to serialize
|
|
86
|
+
* @returns Borsh-serialized bytes
|
|
87
|
+
*/
|
|
88
|
+
export function serializeStateInit(stateInit) {
|
|
89
|
+
let codeIdentifier;
|
|
90
|
+
if (stateInit.code.type === "accountId") {
|
|
91
|
+
codeIdentifier = { AccountId: stateInit.code.accountId };
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
codeIdentifier = { CodeHash: Array.from(stateInit.code.hash) };
|
|
95
|
+
}
|
|
96
|
+
// Sort the data map by keys to ensure deterministic serialization
|
|
97
|
+
// NEP-616 specifies BTreeMap which has sorted order, but JavaScript Map
|
|
98
|
+
// maintains insertion order. We must sort to ensure the same key-value pairs
|
|
99
|
+
// produce the same account ID regardless of insertion order.
|
|
100
|
+
const sortedData = new Map(Array.from(stateInit.data.entries()).sort((a, b) => {
|
|
101
|
+
const [keyA] = a;
|
|
102
|
+
const [keyB] = b;
|
|
103
|
+
// Compare byte-by-byte
|
|
104
|
+
for (let i = 0; i < Math.min(keyA.length, keyB.length); i++) {
|
|
105
|
+
const byteA = keyA[i];
|
|
106
|
+
const byteB = keyB[i];
|
|
107
|
+
if (byteA !== undefined && byteB !== undefined && byteA !== byteB) {
|
|
108
|
+
return byteA - byteB;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// If all bytes match, shorter key comes first
|
|
112
|
+
return keyA.length - keyB.length;
|
|
113
|
+
}));
|
|
114
|
+
return StateInitSchema.serialize({
|
|
115
|
+
V1: {
|
|
116
|
+
code: codeIdentifier,
|
|
117
|
+
data: sortedData,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Derive a deterministic account ID from a StateInit according to NEP-616.
|
|
123
|
+
*
|
|
124
|
+
* The account ID is derived as: `"0s" + hex(keccak256(borsh(state_init))[12..32])`
|
|
125
|
+
*
|
|
126
|
+
* This produces a 42-character account ID that:
|
|
127
|
+
* - Starts with "0s" prefix (distinguishes from Ethereum implicit accounts "0x")
|
|
128
|
+
* - Followed by 40 hex characters (20 bytes from the keccak256 hash)
|
|
129
|
+
*
|
|
130
|
+
* @param stateInit - StateInit object or options to create one
|
|
131
|
+
* @returns The deterministically derived account ID
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* // From a global contract by account ID
|
|
136
|
+
* const accountId = deriveAccountId({
|
|
137
|
+
* code: { accountId: "publisher.near" },
|
|
138
|
+
* })
|
|
139
|
+
* // => "0s1234567890abcdef1234567890abcdef12345678"
|
|
140
|
+
*
|
|
141
|
+
* // From a global contract by code hash
|
|
142
|
+
* const accountId = deriveAccountId({
|
|
143
|
+
* code: { codeHash: hashBytes },
|
|
144
|
+
* })
|
|
145
|
+
*
|
|
146
|
+
* // With initial storage data
|
|
147
|
+
* const accountId = deriveAccountId({
|
|
148
|
+
* code: { accountId: "publisher.near" },
|
|
149
|
+
* data: new Map([[key1, value1], [key2, value2]]),
|
|
150
|
+
* })
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
export function deriveAccountId(options) {
|
|
154
|
+
const stateInit = createStateInit(options);
|
|
155
|
+
const serialized = serializeStateInit(stateInit);
|
|
156
|
+
const hash = keccak_256(serialized);
|
|
157
|
+
// Take last 20 bytes (indices 12-32) of the hash
|
|
158
|
+
const suffix = hash.slice(12, 32);
|
|
159
|
+
return `0s${hex.encode(suffix)}`;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Verify that an account ID matches the expected deterministic derivation from a StateInit.
|
|
163
|
+
*
|
|
164
|
+
* @param accountId - The account ID to verify
|
|
165
|
+
* @param options - StateInit options to derive the expected account ID from
|
|
166
|
+
* @returns true if the account ID matches the derivation, false otherwise
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* const isValid = verifyDeterministicAccountId(
|
|
171
|
+
* "0s1234567890abcdef1234567890abcdef12345678",
|
|
172
|
+
* { code: { accountId: "publisher.near" } }
|
|
173
|
+
* )
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
export function verifyDeterministicAccountId(accountId, options) {
|
|
177
|
+
const expected = deriveAccountId(options);
|
|
178
|
+
return accountId === expected;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Check if an account ID is a deterministic account ID (NEP-616).
|
|
182
|
+
*
|
|
183
|
+
* Deterministic account IDs start with "0s" followed by 40 hex characters.
|
|
184
|
+
*
|
|
185
|
+
* @param accountId - The account ID to check
|
|
186
|
+
* @returns true if it's a deterministic account ID, false otherwise
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```typescript
|
|
190
|
+
* isDeterministicAccountId("0s1234567890abcdef1234567890abcdef12345678") // true
|
|
191
|
+
* isDeterministicAccountId("alice.near") // false
|
|
192
|
+
* isDeterministicAccountId("0x1234567890abcdef1234567890abcdef12345678") // false (Ethereum)
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
export function isDeterministicAccountId(accountId) {
|
|
196
|
+
// Must be exactly 42 characters: "0s" + 40 hex chars
|
|
197
|
+
if (accountId.length !== 42) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
// Must start with "0s"
|
|
201
|
+
if (!accountId.startsWith("0s")) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
// Rest must be valid hex
|
|
205
|
+
const hexPart = accountId.slice(2);
|
|
206
|
+
return /^[0-9a-f]+$/.test(hexPart);
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=state-init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-init.js","sourceRoot":"","sources":["../../src/utils/state-init.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "near-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "A simple, intuitive TypeScript library for interacting with NEAR Protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
}
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@biomejs/biome": "2.3.
|
|
70
|
+
"@biomejs/biome": "2.3.8",
|
|
71
71
|
"@changesets/cli": "^2.29.7",
|
|
72
72
|
"@hot-labs/near-connect": "^0.6.9",
|
|
73
73
|
"@near-js/transactions": "^2.5.1",
|