near-kit 0.0.0 → 0.2.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/LICENSE +21 -0
- package/README.md +473 -2
- package/dist/contracts/contract.d.ts +63 -0
- package/dist/contracts/contract.d.ts.map +1 -0
- package/dist/contracts/contract.js +42 -0
- package/dist/contracts/contract.js.map +1 -0
- package/dist/contracts/index.d.ts +5 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +5 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/core/actions.d.ts +193 -0
- package/dist/core/actions.d.ts.map +1 -0
- package/dist/core/actions.js +195 -0
- package/dist/core/actions.js.map +1 -0
- package/dist/core/config-schemas.d.ts +179 -0
- package/dist/core/config-schemas.d.ts.map +1 -0
- package/dist/core/config-schemas.js +169 -0
- package/dist/core/config-schemas.js.map +1 -0
- package/dist/core/constants.d.ts +43 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +49 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/near.d.ts +301 -0
- package/dist/core/near.d.ts.map +1 -0
- package/dist/core/near.js +504 -0
- package/dist/core/near.js.map +1 -0
- package/dist/core/nonce-manager.d.ts +39 -0
- package/dist/core/nonce-manager.d.ts.map +1 -0
- package/dist/core/nonce-manager.js +73 -0
- package/dist/core/nonce-manager.js.map +1 -0
- package/dist/core/rpc/rpc-error-handler.d.ts +60 -0
- package/dist/core/rpc/rpc-error-handler.d.ts.map +1 -0
- package/dist/core/rpc/rpc-error-handler.js +324 -0
- package/dist/core/rpc/rpc-error-handler.js.map +1 -0
- package/dist/core/rpc/rpc-schemas.d.ts +1812 -0
- package/dist/core/rpc/rpc-schemas.d.ts.map +1 -0
- package/dist/core/rpc/rpc-schemas.js +424 -0
- package/dist/core/rpc/rpc-schemas.js.map +1 -0
- package/dist/core/rpc/rpc.d.ts +117 -0
- package/dist/core/rpc/rpc.d.ts.map +1 -0
- package/dist/core/rpc/rpc.js +325 -0
- package/dist/core/rpc/rpc.js.map +1 -0
- package/dist/core/schema.d.ts +1188 -0
- package/dist/core/schema.d.ts.map +1 -0
- package/dist/core/schema.js +396 -0
- package/dist/core/schema.js.map +1 -0
- package/dist/core/transaction.d.ts +390 -0
- package/dist/core/transaction.d.ts.map +1 -0
- package/dist/core/transaction.js +653 -0
- package/dist/core/transaction.js.map +1 -0
- package/dist/core/types.d.ts +271 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +9 -0
- package/dist/core/types.js.map +1 -0
- package/dist/errors/index.d.ts +226 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +366 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/keys/credential-schemas.d.ts +98 -0
- package/dist/keys/credential-schemas.d.ts.map +1 -0
- package/dist/keys/credential-schemas.js +128 -0
- package/dist/keys/credential-schemas.js.map +1 -0
- package/dist/keys/file-keystore.d.ts +130 -0
- package/dist/keys/file-keystore.d.ts.map +1 -0
- package/dist/keys/file-keystore.js +266 -0
- package/dist/keys/file-keystore.js.map +1 -0
- package/dist/keys/in-memory-keystore.d.ts +71 -0
- package/dist/keys/in-memory-keystore.d.ts.map +1 -0
- package/dist/keys/in-memory-keystore.js +85 -0
- package/dist/keys/in-memory-keystore.js.map +1 -0
- package/dist/keys/index.d.ts +14 -0
- package/dist/keys/index.d.ts.map +1 -0
- package/dist/keys/index.js +20 -0
- package/dist/keys/index.js.map +1 -0
- package/dist/keys/native-keystore.d.ts +111 -0
- package/dist/keys/native-keystore.d.ts.map +1 -0
- package/dist/keys/native-keystore.js +167 -0
- package/dist/keys/native-keystore.js.map +1 -0
- package/dist/keys/rotating-keystore.d.ts +207 -0
- package/dist/keys/rotating-keystore.d.ts.map +1 -0
- package/dist/keys/rotating-keystore.js +240 -0
- package/dist/keys/rotating-keystore.js.map +1 -0
- package/dist/sandbox/index.d.ts +6 -0
- package/dist/sandbox/index.d.ts.map +1 -0
- package/dist/sandbox/index.js +5 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sandbox/sandbox.d.ts +55 -0
- package/dist/sandbox/sandbox.d.ts.map +1 -0
- package/dist/sandbox/sandbox.js +341 -0
- package/dist/sandbox/sandbox.js.map +1 -0
- package/dist/utils/amount.d.ts +76 -0
- package/dist/utils/amount.d.ts.map +1 -0
- package/dist/utils/amount.js +137 -0
- package/dist/utils/amount.js.map +1 -0
- package/dist/utils/gas.d.ts +69 -0
- package/dist/utils/gas.d.ts.map +1 -0
- package/dist/utils/gas.js +92 -0
- package/dist/utils/gas.js.map +1 -0
- package/dist/utils/index.d.ts +14 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +14 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/key.d.ts +117 -0
- package/dist/utils/key.d.ts.map +1 -0
- package/dist/utils/key.js +270 -0
- package/dist/utils/key.js.map +1 -0
- package/dist/utils/nep413.d.ts +97 -0
- package/dist/utils/nep413.d.ts.map +1 -0
- package/dist/utils/nep413.js +154 -0
- package/dist/utils/nep413.js.map +1 -0
- package/dist/utils/validation.d.ts +114 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +150 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/wallets/adapters.d.ts +119 -0
- package/dist/wallets/adapters.d.ts.map +1 -0
- package/dist/wallets/adapters.js +267 -0
- package/dist/wallets/adapters.js.map +1 -0
- package/dist/wallets/index.d.ts +11 -0
- package/dist/wallets/index.d.ts.map +1 -0
- package/dist/wallets/index.js +2 -0
- package/dist/wallets/index.js.map +1 -0
- package/dist/wallets/types.d.ts +99 -0
- package/dist/wallets/types.d.ts.map +1 -0
- package/dist/wallets/types.js +10 -0
- package/dist/wallets/types.js.map +1 -0
- package/package.json +78 -7
- package/index.js +0 -1
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main NEAR client class
|
|
3
|
+
*/
|
|
4
|
+
import { createContract } from "../contracts/contract.js";
|
|
5
|
+
import { NearError } from "../errors/index.js";
|
|
6
|
+
import { InMemoryKeyStore } from "../keys/index.js";
|
|
7
|
+
import { parseKey } from "../utils/key.js";
|
|
8
|
+
import { generateNep413Nonce } from "../utils/nep413.js";
|
|
9
|
+
import { normalizeAmount, normalizeGas } from "../utils/validation.js";
|
|
10
|
+
import * as actions from "./actions.js";
|
|
11
|
+
import { NearConfigSchema, resolveNetworkConfig, } from "./config-schemas.js";
|
|
12
|
+
import { DEFAULT_FUNCTION_CALL_GAS } from "./constants.js";
|
|
13
|
+
import { RpcClient } from "./rpc/rpc.js";
|
|
14
|
+
import { TransactionBuilder } from "./transaction.js";
|
|
15
|
+
/**
|
|
16
|
+
* Main client for interacting with the NEAR blockchain.
|
|
17
|
+
*
|
|
18
|
+
* Wraps RPC access, key management, wallet integrations, and the fluent
|
|
19
|
+
* transaction builder. Most applications create one `Near` instance per
|
|
20
|
+
* network and reuse it for all operations.
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* Configure the client with {@link NearConfig} to choose networks, key stores,
|
|
24
|
+
* wallets, and retry behavior. For a guided overview see
|
|
25
|
+
* `docs/01-getting-started.md` and `docs/02-core-concepts.md`.
|
|
26
|
+
*/
|
|
27
|
+
export class Near {
|
|
28
|
+
constructor(config = {}) {
|
|
29
|
+
const validatedConfig = NearConfigSchema.parse(config);
|
|
30
|
+
this._initializeRpc(validatedConfig);
|
|
31
|
+
this._resolveKeyStore(validatedConfig);
|
|
32
|
+
this._resolveSigner(validatedConfig, config);
|
|
33
|
+
if (validatedConfig.defaultSignerId) {
|
|
34
|
+
this.defaultSignerId = validatedConfig.defaultSignerId;
|
|
35
|
+
}
|
|
36
|
+
this.defaultWaitUntil =
|
|
37
|
+
validatedConfig.defaultWaitUntil || "EXECUTED_OPTIMISTIC";
|
|
38
|
+
this.wallet = validatedConfig.wallet;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Initialize RPC client from configuration
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
_initializeRpc(validatedConfig) {
|
|
45
|
+
const networkConfig = resolveNetworkConfig(validatedConfig.network);
|
|
46
|
+
const rpcUrl = validatedConfig.rpcUrl || networkConfig.rpcUrl;
|
|
47
|
+
this.rpc = new RpcClient(rpcUrl, validatedConfig.headers, validatedConfig.retryConfig);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolve and initialize keystore from configuration
|
|
51
|
+
* @internal
|
|
52
|
+
*/
|
|
53
|
+
_resolveKeyStore(validatedConfig) {
|
|
54
|
+
this.keyStore = this.resolveKeyStore(validatedConfig.keyStore);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Resolve and initialize signer from configuration
|
|
58
|
+
* Handles privateKey, custom signer, and sandbox root key auto-detection
|
|
59
|
+
* @internal
|
|
60
|
+
*/
|
|
61
|
+
_resolveSigner(validatedConfig, originalConfig) {
|
|
62
|
+
const signer = validatedConfig.signer;
|
|
63
|
+
const privateKey = validatedConfig.privateKey;
|
|
64
|
+
if (signer) {
|
|
65
|
+
this.signer = signer;
|
|
66
|
+
}
|
|
67
|
+
else if (privateKey) {
|
|
68
|
+
const keyPair = typeof privateKey === "string"
|
|
69
|
+
? parseKey(privateKey)
|
|
70
|
+
: parseKey(privateKey.toString());
|
|
71
|
+
this.signer = async (message) => keyPair.sign(message);
|
|
72
|
+
// If network is a Sandbox-like object with rootAccount, add key to keyStore
|
|
73
|
+
// Use original config.network (before validation) to preserve extra properties
|
|
74
|
+
const network = originalConfig.network;
|
|
75
|
+
if (network && typeof network === "object" && "rootAccount" in network) {
|
|
76
|
+
const rootAccount = network
|
|
77
|
+
.rootAccount;
|
|
78
|
+
void this.keyStore.add(rootAccount.id, keyPair);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Auto-add sandbox root key to keyStore if available and no explicit signer/privateKey
|
|
82
|
+
// This enables simple usage like: new Near({ network: sandbox })
|
|
83
|
+
// while still allowing multi-account scenarios via keyStore
|
|
84
|
+
if (!signer && !privateKey) {
|
|
85
|
+
const network = originalConfig.network;
|
|
86
|
+
if (network && typeof network === "object" && "rootAccount" in network) {
|
|
87
|
+
const rootAccount = network;
|
|
88
|
+
// Guard: only auto-add if both id and secretKey are non-empty strings
|
|
89
|
+
if (rootAccount.rootAccount?.id &&
|
|
90
|
+
rootAccount.rootAccount?.secretKey &&
|
|
91
|
+
typeof rootAccount.rootAccount.secretKey === "string") {
|
|
92
|
+
const keyPair = parseKey(rootAccount.rootAccount.secretKey);
|
|
93
|
+
// Store the promise to ensure async keystores complete initialization
|
|
94
|
+
this.pendingKeyStoreInit = this.keyStore.add(rootAccount.rootAccount.id, keyPair);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Ensure any pending keystore initialization is complete
|
|
101
|
+
* @internal
|
|
102
|
+
*/
|
|
103
|
+
async ensureKeyStoreReady() {
|
|
104
|
+
if (this.pendingKeyStoreInit) {
|
|
105
|
+
await this.pendingKeyStoreInit;
|
|
106
|
+
delete this.pendingKeyStoreInit;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Resolve key store from config input
|
|
111
|
+
* @internal
|
|
112
|
+
*/
|
|
113
|
+
resolveKeyStore(keyStoreConfig) {
|
|
114
|
+
if (!keyStoreConfig) {
|
|
115
|
+
return new InMemoryKeyStore();
|
|
116
|
+
}
|
|
117
|
+
if (typeof keyStoreConfig === "string") {
|
|
118
|
+
// Import FileKeyStore dynamically to avoid bundling in browser
|
|
119
|
+
// For now, return in-memory
|
|
120
|
+
return new InMemoryKeyStore();
|
|
121
|
+
}
|
|
122
|
+
if ("add" in keyStoreConfig && "get" in keyStoreConfig) {
|
|
123
|
+
return keyStoreConfig;
|
|
124
|
+
}
|
|
125
|
+
// Record of account -> key mappings
|
|
126
|
+
return new InMemoryKeyStore(keyStoreConfig);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get signer ID from options, default, or wallet
|
|
130
|
+
* @internal
|
|
131
|
+
*/
|
|
132
|
+
async getSignerId(signerId) {
|
|
133
|
+
if (signerId)
|
|
134
|
+
return signerId;
|
|
135
|
+
if (this.defaultSignerId)
|
|
136
|
+
return this.defaultSignerId;
|
|
137
|
+
// Get from wallet if available
|
|
138
|
+
if (this.wallet) {
|
|
139
|
+
const accounts = await this.wallet.getAccounts();
|
|
140
|
+
if (accounts.length === 0) {
|
|
141
|
+
throw new NearError("No accounts connected to wallet", "NO_WALLET_ACCOUNTS");
|
|
142
|
+
}
|
|
143
|
+
// Safe to use non-null assertion after length check
|
|
144
|
+
// biome-ignore lint/style/noNonNullAssertion: verified accounts[0] exists above
|
|
145
|
+
return accounts[0].accountId;
|
|
146
|
+
}
|
|
147
|
+
throw new NearError("No signer ID provided. Set signerId in options or config.", "MISSING_SIGNER");
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Call a view function on a contract (read-only, no gas).
|
|
151
|
+
*
|
|
152
|
+
* @param contractId - Target contract account ID.
|
|
153
|
+
* @param methodName - Name of the view method to call.
|
|
154
|
+
* @param args - Arguments object or raw bytes; defaults to `{}`.
|
|
155
|
+
* @param options - Optional {@link BlockReference} to specify finality or block.
|
|
156
|
+
*
|
|
157
|
+
* @returns Parsed JSON result when the contract returns JSON, otherwise the
|
|
158
|
+
* raw string value typed as `T`.
|
|
159
|
+
*
|
|
160
|
+
* @remarks
|
|
161
|
+
* - View calls are free and do not require a signer or gas.
|
|
162
|
+
* - Errors thrown by the contract surface as {@link ContractExecutionError}.
|
|
163
|
+
*
|
|
164
|
+
* @see NearConfig.defaultWaitUntil
|
|
165
|
+
*/
|
|
166
|
+
async view(contractId, methodName, args = {}, options) {
|
|
167
|
+
const result = await this.rpc.viewFunction(contractId, methodName, args, options);
|
|
168
|
+
// Decode result
|
|
169
|
+
const resultBuffer = new Uint8Array(result.result);
|
|
170
|
+
const resultString = new TextDecoder().decode(resultBuffer);
|
|
171
|
+
if (!resultString) {
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
return JSON.parse(resultString);
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return resultString;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Call a change function on a contract (requires signature and gas).
|
|
183
|
+
*
|
|
184
|
+
* Uses the connected wallet when available, otherwise falls back to the
|
|
185
|
+
* configured signer / private key / key store.
|
|
186
|
+
*
|
|
187
|
+
* @param contractId - Target contract account ID.
|
|
188
|
+
* @param methodName - Name of the change method to call.
|
|
189
|
+
* @param args - Arguments object or raw bytes; defaults to `{}`.
|
|
190
|
+
* @param options - Call options such as gas, attached deposit, signerId and wait level.
|
|
191
|
+
*
|
|
192
|
+
* @returns The decoded contract return value typed as `T`.
|
|
193
|
+
*
|
|
194
|
+
* @throws {NearError} If no signer can be resolved.
|
|
195
|
+
* @throws {FunctionCallError} If the contract panics or returns an error.
|
|
196
|
+
* @throws {InvalidTransactionError} If the transaction itself is invalid.
|
|
197
|
+
* @throws {NetworkError} If the RPC request fails after retries.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* await near.call(
|
|
202
|
+
* "contract.near",
|
|
203
|
+
* "increment",
|
|
204
|
+
* { by: 1 },
|
|
205
|
+
* { attachedDeposit: "1 yocto", gas: "30 Tgas" },
|
|
206
|
+
* )
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
async call(contractId, methodName, args = {}, options = {}) {
|
|
210
|
+
const signerId = await this.getSignerId(options.signerId);
|
|
211
|
+
// Use wallet if available
|
|
212
|
+
if (this.wallet) {
|
|
213
|
+
const argsBytes = args instanceof Uint8Array
|
|
214
|
+
? args
|
|
215
|
+
: new TextEncoder().encode(JSON.stringify(args));
|
|
216
|
+
const gas = options.gas
|
|
217
|
+
? normalizeGas(options.gas)
|
|
218
|
+
: DEFAULT_FUNCTION_CALL_GAS;
|
|
219
|
+
const deposit = options.attachedDeposit
|
|
220
|
+
? normalizeAmount(options.attachedDeposit)
|
|
221
|
+
: "0";
|
|
222
|
+
const result = await this.wallet.signAndSendTransaction({
|
|
223
|
+
signerId,
|
|
224
|
+
receiverId: contractId,
|
|
225
|
+
actions: [
|
|
226
|
+
actions.functionCall(methodName, argsBytes, BigInt(gas), BigInt(deposit)),
|
|
227
|
+
],
|
|
228
|
+
});
|
|
229
|
+
return result;
|
|
230
|
+
}
|
|
231
|
+
// Use private key/signer approach
|
|
232
|
+
const functionCallOptions = {};
|
|
233
|
+
if (options.gas !== undefined) {
|
|
234
|
+
functionCallOptions.gas = options.gas;
|
|
235
|
+
}
|
|
236
|
+
if (options.attachedDeposit !== undefined) {
|
|
237
|
+
functionCallOptions.attachedDeposit = options.attachedDeposit;
|
|
238
|
+
}
|
|
239
|
+
const sendOptions = options.waitUntil
|
|
240
|
+
? { waitUntil: options.waitUntil }
|
|
241
|
+
: {};
|
|
242
|
+
const result = await this.transaction(signerId)
|
|
243
|
+
.functionCall(contractId, methodName, args, functionCallOptions)
|
|
244
|
+
.send(sendOptions);
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Send NEAR tokens to an account.
|
|
249
|
+
*
|
|
250
|
+
* @param receiverId - Account ID that will receive the tokens.
|
|
251
|
+
* @param amount - Amount to send, expressed as {@link Amount} (e.g. `"10 NEAR"` or `"1 yocto"`).
|
|
252
|
+
*
|
|
253
|
+
* @returns The final transaction outcome from the wallet or RPC.
|
|
254
|
+
*
|
|
255
|
+
* @throws {NearError} If no signer can be resolved.
|
|
256
|
+
* @throws {InvalidTransactionError} If the transfer transaction is invalid.
|
|
257
|
+
* @throws {NetworkError} If the RPC request fails after retries.
|
|
258
|
+
*
|
|
259
|
+
* @remarks
|
|
260
|
+
* This is a convenience wrapper over {@link Near.transaction} with a single
|
|
261
|
+
* `transfer` action.
|
|
262
|
+
*/
|
|
263
|
+
async send(receiverId, amount) {
|
|
264
|
+
const signerId = await this.getSignerId();
|
|
265
|
+
// Use wallet if available
|
|
266
|
+
if (this.wallet) {
|
|
267
|
+
const amountYocto = normalizeAmount(amount);
|
|
268
|
+
return await this.wallet.signAndSendTransaction({
|
|
269
|
+
signerId,
|
|
270
|
+
receiverId,
|
|
271
|
+
actions: [actions.transfer(BigInt(amountYocto))],
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
// Use private key/signer approach
|
|
275
|
+
return await this.transaction(signerId).transfer(receiverId, amount).send();
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Sign a message using NEP-413 standard.
|
|
279
|
+
*
|
|
280
|
+
* NEP-413 enables off-chain message signing for authentication and ownership verification
|
|
281
|
+
* without gas fees or blockchain transactions. Useful for:
|
|
282
|
+
* - Login/authentication flows
|
|
283
|
+
* - Proving account ownership
|
|
284
|
+
* - Signing intents for meta-transactions
|
|
285
|
+
* - Off-chain authorization
|
|
286
|
+
*
|
|
287
|
+
* @param params - Message signing parameters
|
|
288
|
+
* @param options - Optional signer ID (defaults to first account)
|
|
289
|
+
* @returns Signed message with account ID, public key, and signature
|
|
290
|
+
*
|
|
291
|
+
* @throws {NearError} If no wallet or keystore is configured
|
|
292
|
+
* @throws {NearError} If the key doesn't support NEP-413 signing
|
|
293
|
+
*
|
|
294
|
+
* @see https://github.com/near/NEPs/blob/master/neps/nep-0413.md
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```typescript
|
|
298
|
+
* // Sign a message for authentication
|
|
299
|
+
* const signedMessage = await near.signMessage({
|
|
300
|
+
* message: "Login to MyApp",
|
|
301
|
+
* recipient: "myapp.near",
|
|
302
|
+
* nonce: crypto.getRandomValues(new Uint8Array(32)),
|
|
303
|
+
* })
|
|
304
|
+
*
|
|
305
|
+
* // Send to backend for verification
|
|
306
|
+
* await fetch("/api/auth", {
|
|
307
|
+
* method: "POST",
|
|
308
|
+
* body: JSON.stringify(signedMessage),
|
|
309
|
+
* })
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
async signMessage(params, options) {
|
|
313
|
+
const signerId = await this.getSignerId(options?.signerId);
|
|
314
|
+
// Add nonce if not provided
|
|
315
|
+
const fullParams = {
|
|
316
|
+
...params,
|
|
317
|
+
nonce: "nonce" in params ? params.nonce : generateNep413Nonce(),
|
|
318
|
+
};
|
|
319
|
+
// Try wallet first if available
|
|
320
|
+
if (this.wallet?.signMessage) {
|
|
321
|
+
try {
|
|
322
|
+
return await this.wallet.signMessage(fullParams);
|
|
323
|
+
}
|
|
324
|
+
catch (error) {
|
|
325
|
+
// Fall through to keystore if wallet doesn't support it
|
|
326
|
+
console.warn("Wallet signMessage failed, trying keystore:", error);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// Use keystore approach
|
|
330
|
+
// Ensure any pending keystore initialization is complete
|
|
331
|
+
await this.ensureKeyStoreReady();
|
|
332
|
+
const keyPair = await this.keyStore.get(signerId);
|
|
333
|
+
if (!keyPair) {
|
|
334
|
+
throw new NearError(`No key found for account ${signerId}. Add a key using keyStore.add() or configure a wallet.`, "NO_KEY_FOUND");
|
|
335
|
+
}
|
|
336
|
+
if (!keyPair.signNep413Message) {
|
|
337
|
+
throw new NearError("Key pair does not support NEP-413 message signing", "UNSUPPORTED_OPERATION");
|
|
338
|
+
}
|
|
339
|
+
return keyPair.signNep413Message(signerId, fullParams);
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Get account balance in NEAR.
|
|
343
|
+
*
|
|
344
|
+
* @param accountId - Account ID to query.
|
|
345
|
+
* @param options - Optional {@link BlockReference} to control finality or block.
|
|
346
|
+
*
|
|
347
|
+
* @returns Balance formatted as `"X.YY NEAR"`.
|
|
348
|
+
*
|
|
349
|
+
* @throws {AccountDoesNotExistError} If the account does not exist.
|
|
350
|
+
* @throws {NetworkError} If the RPC request fails.
|
|
351
|
+
*
|
|
352
|
+
* @remarks
|
|
353
|
+
* This is a convenience helper over {@link RpcClient.getAccount}. For more
|
|
354
|
+
* detailed information (storage, locked balance, etc.) call `rpc.getAccount`
|
|
355
|
+
* directly.
|
|
356
|
+
*/
|
|
357
|
+
async getBalance(accountId, options) {
|
|
358
|
+
// RPC client now throws AccountDoesNotExistError directly
|
|
359
|
+
const account = await this.rpc.getAccount(accountId, options);
|
|
360
|
+
// Convert yoctoNEAR to NEAR
|
|
361
|
+
const balanceYocto = BigInt(account.amount);
|
|
362
|
+
const balanceNear = Number(balanceYocto) / 1e24;
|
|
363
|
+
return balanceNear.toFixed(2);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Check if an account exists.
|
|
367
|
+
*
|
|
368
|
+
* @param accountId - Account ID to check.
|
|
369
|
+
* @param options - Optional {@link BlockReference} to control finality or block.
|
|
370
|
+
*
|
|
371
|
+
* @returns `true` if the account exists, `false` otherwise.
|
|
372
|
+
*
|
|
373
|
+
* @remarks
|
|
374
|
+
* This method swallows all errors and returns `false` on failure. Use
|
|
375
|
+
* {@link RpcClient.getAccount} if you need to distinguish error causes.
|
|
376
|
+
*/
|
|
377
|
+
async accountExists(accountId, options) {
|
|
378
|
+
try {
|
|
379
|
+
await this.rpc.getAccount(accountId, options);
|
|
380
|
+
return true;
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Get transaction status with detailed receipt information
|
|
388
|
+
*
|
|
389
|
+
* Queries the status of a transaction by hash using the EXPERIMENTAL_tx_status RPC method,
|
|
390
|
+
* returning the final transaction result with detailed receipt information.
|
|
391
|
+
*
|
|
392
|
+
* @param txHash - Transaction hash to query
|
|
393
|
+
* @param senderAccountId - Account ID that sent the transaction (used to determine shard)
|
|
394
|
+
* @param waitUntil - Optional execution level to wait for (default: "EXECUTED_OPTIMISTIC")
|
|
395
|
+
*
|
|
396
|
+
* @returns Transaction status with receipts, typed based on waitUntil parameter
|
|
397
|
+
*
|
|
398
|
+
* @throws {InvalidTransactionError} If transaction execution failed
|
|
399
|
+
* @throws {NetworkError} If network request failed
|
|
400
|
+
*
|
|
401
|
+
* @example
|
|
402
|
+
* ```typescript
|
|
403
|
+
* // Get transaction status with default wait level
|
|
404
|
+
* const status = await near.getTransactionStatus(
|
|
405
|
+
* '7AfonAhbK4ZbdBU9VPcQdrTZVZBXE25HmZAMEABs9To1',
|
|
406
|
+
* 'alice.near'
|
|
407
|
+
* )
|
|
408
|
+
*
|
|
409
|
+
* // Wait for full finality
|
|
410
|
+
* const finalStatus = await near.getTransactionStatus(
|
|
411
|
+
* '7AfonAhbK4ZbdBU9VPcQdrTZVZBXE25HmZAMEABs9To1',
|
|
412
|
+
* 'alice.near',
|
|
413
|
+
* 'FINAL'
|
|
414
|
+
* )
|
|
415
|
+
*
|
|
416
|
+
* // Access receipt details
|
|
417
|
+
* console.log('Receipts:', finalStatus.receipts)
|
|
418
|
+
* ```
|
|
419
|
+
*
|
|
420
|
+
* @see {@link https://docs.near.org/api/rpc/transactions#transaction-status-with-receipts NEAR RPC Documentation}
|
|
421
|
+
*/
|
|
422
|
+
async getTransactionStatus(txHash, senderAccountId, waitUntil) {
|
|
423
|
+
return this.rpc.getTransactionStatus(txHash, senderAccountId, waitUntil);
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Get basic network status information.
|
|
427
|
+
*
|
|
428
|
+
* @returns An object containing `chainId`, `latestBlockHeight`, and `syncing` flag.
|
|
429
|
+
*/
|
|
430
|
+
async getStatus() {
|
|
431
|
+
const status = await this.rpc.getStatus();
|
|
432
|
+
return {
|
|
433
|
+
chainId: status.chain_id,
|
|
434
|
+
latestBlockHeight: status.sync_info.latest_block_height,
|
|
435
|
+
syncing: status.sync_info.syncing,
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Batch multiple read operations.
|
|
440
|
+
*
|
|
441
|
+
* @param promises - Promises to execute in parallel.
|
|
442
|
+
*
|
|
443
|
+
* @returns A tuple of resolved values preserving the input order.
|
|
444
|
+
*
|
|
445
|
+
* @remarks
|
|
446
|
+
* This is a thin wrapper over `Promise.all` with a tuple-friendly signature.
|
|
447
|
+
* It does not perform any RPC-level batching.
|
|
448
|
+
*/
|
|
449
|
+
async batch(...promises) {
|
|
450
|
+
return Promise.all(promises);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Create a transaction builder for the specified signer account.
|
|
454
|
+
*
|
|
455
|
+
* The `signerId` determines which account will sign and send this transaction.
|
|
456
|
+
* This account must have keys available in the configured keyStore, privateKey,
|
|
457
|
+
* custom signer, or be connected via wallet.
|
|
458
|
+
*
|
|
459
|
+
* @param signerId - The account ID that will sign and pay for this transaction
|
|
460
|
+
*
|
|
461
|
+
* @returns A transaction builder for chaining actions
|
|
462
|
+
*
|
|
463
|
+
* @example
|
|
464
|
+
* ```typescript
|
|
465
|
+
* // Alice sends NEAR to Bob
|
|
466
|
+
* await near.transaction('alice.near')
|
|
467
|
+
* .transfer('bob.near', '10 NEAR')
|
|
468
|
+
* .send()
|
|
469
|
+
*
|
|
470
|
+
* // Alice calls a contract and creates a new account
|
|
471
|
+
* await near.transaction('alice.near')
|
|
472
|
+
* .functionCall('market.near', 'buy', { id: 123 })
|
|
473
|
+
* .createAccount('sub.alice.near')
|
|
474
|
+
* .transfer('sub.alice.near', '5 NEAR')
|
|
475
|
+
* .send()
|
|
476
|
+
* ```
|
|
477
|
+
*
|
|
478
|
+
* @see {@link TransactionBuilder} for available actions
|
|
479
|
+
*/
|
|
480
|
+
transaction(signerId) {
|
|
481
|
+
return new TransactionBuilder(signerId, this.rpc, this.keyStore, this.signer, this.defaultWaitUntil, this.wallet, this.pendingKeyStoreInit ? () => this.ensureKeyStoreReady() : undefined);
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Create a type-safe contract interface.
|
|
485
|
+
*
|
|
486
|
+
* @param contractId - Account ID of the target contract.
|
|
487
|
+
*
|
|
488
|
+
* @returns A proxy implementing your {@link ContractMethods} interface.
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* ```typescript
|
|
492
|
+
* type Counter = Contract<{
|
|
493
|
+
* view: { get_count: () => Promise<number> }
|
|
494
|
+
* call: { increment: () => Promise<void> }
|
|
495
|
+
* }>
|
|
496
|
+
*
|
|
497
|
+
* const counter = near.contract<Counter>("counter.near")
|
|
498
|
+
* ```
|
|
499
|
+
*/
|
|
500
|
+
contract(contractId) {
|
|
501
|
+
return createContract(this, contractId);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
//# sourceMappingURL=near.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"near.js","sourceRoot":"","sources":["../../src/core/near.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages nonces for concurrent transactions.
|
|
3
|
+
*
|
|
4
|
+
* Prevents nonce collisions when sending multiple transactions in parallel
|
|
5
|
+
* by caching nonces in memory and incrementing them locally.
|
|
6
|
+
*
|
|
7
|
+
* @internal Used by {@link TransactionBuilder}; not typically needed directly.
|
|
8
|
+
*/
|
|
9
|
+
export declare class NonceManager {
|
|
10
|
+
private nonces;
|
|
11
|
+
private fetching;
|
|
12
|
+
/**
|
|
13
|
+
* Get the next nonce for an account and public key
|
|
14
|
+
*
|
|
15
|
+
* Fetches from blockchain on first call, then increments locally.
|
|
16
|
+
* Handles concurrent calls gracefully by deduplicating fetches.
|
|
17
|
+
*
|
|
18
|
+
* @param accountId - Account ID to get nonce for
|
|
19
|
+
* @param publicKey - Public key to get nonce for
|
|
20
|
+
* @param fetchFromBlockchain - Callback to fetch current nonce from blockchain
|
|
21
|
+
* @returns Next nonce to use for transaction
|
|
22
|
+
*/
|
|
23
|
+
getNextNonce(accountId: string, publicKey: string, fetchFromBlockchain: () => Promise<bigint>): Promise<bigint>;
|
|
24
|
+
/**
|
|
25
|
+
* Invalidate cached nonce for an account and public key
|
|
26
|
+
*
|
|
27
|
+
* Call this when an InvalidNonceError occurs to force a fresh fetch
|
|
28
|
+
* from the blockchain on the next transaction.
|
|
29
|
+
*
|
|
30
|
+
* @param accountId - Account ID to invalidate
|
|
31
|
+
* @param publicKey - Public key to invalidate
|
|
32
|
+
*/
|
|
33
|
+
invalidate(accountId: string, publicKey: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Clear all cached nonces
|
|
36
|
+
*/
|
|
37
|
+
clear(): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=nonce-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nonce-manager.d.ts","sourceRoot":"","sources":["../../src/core/nonce-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,QAAQ,CAAmC;IAEnD;;;;;;;;;;OAUG;IACG,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,mBAAmB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GACzC,OAAO,CAAC,MAAM,CAAC;IAkClB;;;;;;;;OAQG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAItD;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages nonces for concurrent transactions.
|
|
3
|
+
*
|
|
4
|
+
* Prevents nonce collisions when sending multiple transactions in parallel
|
|
5
|
+
* by caching nonces in memory and incrementing them locally.
|
|
6
|
+
*
|
|
7
|
+
* @internal Used by {@link TransactionBuilder}; not typically needed directly.
|
|
8
|
+
*/
|
|
9
|
+
export class NonceManager {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.nonces = new Map();
|
|
12
|
+
this.fetching = new Map();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get the next nonce for an account and public key
|
|
16
|
+
*
|
|
17
|
+
* Fetches from blockchain on first call, then increments locally.
|
|
18
|
+
* Handles concurrent calls gracefully by deduplicating fetches.
|
|
19
|
+
*
|
|
20
|
+
* @param accountId - Account ID to get nonce for
|
|
21
|
+
* @param publicKey - Public key to get nonce for
|
|
22
|
+
* @param fetchFromBlockchain - Callback to fetch current nonce from blockchain
|
|
23
|
+
* @returns Next nonce to use for transaction
|
|
24
|
+
*/
|
|
25
|
+
async getNextNonce(accountId, publicKey, fetchFromBlockchain) {
|
|
26
|
+
const key = `${accountId}:${publicKey}`;
|
|
27
|
+
// Wait if another call is already fetching for this key
|
|
28
|
+
const pendingFetch = this.fetching.get(key);
|
|
29
|
+
if (pendingFetch) {
|
|
30
|
+
await pendingFetch;
|
|
31
|
+
}
|
|
32
|
+
// Fetch from blockchain if not cached
|
|
33
|
+
if (!this.nonces.has(key)) {
|
|
34
|
+
const fetchPromise = fetchFromBlockchain()
|
|
35
|
+
.then((blockchainNonce) => {
|
|
36
|
+
this.nonces.set(key, blockchainNonce + 1n);
|
|
37
|
+
this.fetching.delete(key);
|
|
38
|
+
})
|
|
39
|
+
.catch((error) => {
|
|
40
|
+
this.fetching.delete(key);
|
|
41
|
+
throw error;
|
|
42
|
+
});
|
|
43
|
+
this.fetching.set(key, fetchPromise);
|
|
44
|
+
await fetchPromise;
|
|
45
|
+
}
|
|
46
|
+
// Return current nonce and increment for next call
|
|
47
|
+
const nonce = this.nonces.get(key);
|
|
48
|
+
if (nonce === undefined) {
|
|
49
|
+
throw new Error(`Nonce not found for ${key} after fetch`);
|
|
50
|
+
}
|
|
51
|
+
this.nonces.set(key, nonce + 1n);
|
|
52
|
+
return nonce;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Invalidate cached nonce for an account and public key
|
|
56
|
+
*
|
|
57
|
+
* Call this when an InvalidNonceError occurs to force a fresh fetch
|
|
58
|
+
* from the blockchain on the next transaction.
|
|
59
|
+
*
|
|
60
|
+
* @param accountId - Account ID to invalidate
|
|
61
|
+
* @param publicKey - Public key to invalidate
|
|
62
|
+
*/
|
|
63
|
+
invalidate(accountId, publicKey) {
|
|
64
|
+
this.nonces.delete(`${accountId}:${publicKey}`);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Clear all cached nonces
|
|
68
|
+
*/
|
|
69
|
+
clear() {
|
|
70
|
+
this.nonces.clear();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=nonce-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nonce-manager.js","sourceRoot":"","sources":["../../src/core/nonce-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,OAAO,YAAY;IAAzB;QACU,WAAM,GAAG,IAAI,GAAG,EAAkB,CAAA;QAClC,aAAQ,GAAG,IAAI,GAAG,EAAyB,CAAA;IAsErD,CAAC;IApEC;;;;;;;;;;OAUG;IACH,KAAK,CAAC,YAAY,CAChB,SAAiB,EACjB,SAAiB,EACjB,mBAA0C;QAE1C,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,SAAS,EAAE,CAAA;QAEvC,wDAAwD;QACxD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,YAAY,CAAA;QACpB,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,YAAY,GAAG,mBAAmB,EAAE;iBACvC,IAAI,CAAC,CAAC,eAAe,EAAE,EAAE;gBACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,GAAG,EAAE,CAAC,CAAA;gBAC1C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC3B,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACf,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBACzB,MAAM,KAAK,CAAA;YACb,CAAC,CAAC,CAAA;YAEJ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;YACpC,MAAM,YAAY,CAAA;QACpB,CAAC;QAED,mDAAmD;QACnD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAClC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,uBAAuB,GAAG,cAAc,CAAC,CAAA;QAC3D,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,GAAG,EAAE,CAAC,CAAA;QAChC,OAAO,KAAK,CAAA;IACd,CAAC;IAED;;;;;;;;OAQG;IACH,UAAU,CAAC,SAAiB,EAAE,SAAiB;QAC7C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,SAAS,IAAI,SAAS,EAAE,CAAC,CAAA;IACjD,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;CACF"}
|