near-kit 0.8.2 → 0.8.3

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 DELETED
@@ -1,495 +0,0 @@
1
- # near-kit
2
-
3
- [![codecov](https://codecov.io/gh/r-near/near-kit/graph/badge.svg?token=F52NQ1DYG1)](https://codecov.io/gh/r-near/near-kit)
4
- [![npm version](https://img.shields.io/npm/v/near-kit.svg)](https://www.npmjs.com/package/near-kit)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue.svg)](https://www.typescriptlang.org/)
7
-
8
- A simple, intuitive TypeScript library for interacting with NEAR Protocol. Designed to feel like a modern fetch library - easy for beginners, powerful for advanced users.
9
-
10
- **[📚 Full Documentation](https://kit.near.tools)**
11
-
12
- ## Features
13
-
14
- - **Simple things should be simple** - One-line commands for common operations
15
- - **Type safety everywhere** - Full TypeScript support with IDE autocomplete
16
- - **Progressive complexity** - Basic API for simple needs, advanced features when required
17
- - **Powerful transaction builder** - Fluent, human-readable API for transactions
18
- - **Wallet-ready** - Full support for [HOT Connector](https://github.com/azbang/hot-connector) and [NEAR Wallet Selector](https://github.com/near/wallet-selector), drop-in integration
19
-
20
- ## Installation
21
-
22
- ```bash
23
- npm install near-kit
24
- # or
25
- bun install near-kit
26
- ```
27
-
28
- ## Quick Start
29
-
30
- ```typescript
31
- import { Near } from "near-kit"
32
-
33
- // Initialize for backend/scripts
34
- const near = new Near({
35
- network: "testnet",
36
- privateKey: "ed25519:...",
37
- defaultSignerId: "alice.testnet",
38
- })
39
-
40
- // View methods (read-only, no gas)
41
- const balance = await near.view("example.testnet", "get_balance", {
42
- account_id: "alice.testnet",
43
- })
44
-
45
- // Call methods (requires signature, costs gas)
46
- await near.call(
47
- "example.testnet",
48
- "increment",
49
- {},
50
- { attachedDeposit: "0.1 NEAR" }
51
- )
52
-
53
- // Send NEAR tokens
54
- await near.send("bob.testnet", "5 NEAR")
55
- ```
56
-
57
- ## Getting Started
58
-
59
- near-kit provides a unified API that works across different environments. Configuration varies by environment, but the API for calling contracts, sending transactions, and building transactions remains identical.
60
-
61
- ### Backend & Scripts
62
-
63
- For local testing, use the sandbox (no network or key configuration needed):
64
-
65
- ```typescript
66
- import { Sandbox } from "near-kit"
67
-
68
- const sandbox = await Sandbox.start()
69
- const near = new Near({ network: sandbox })
70
-
71
- // Test with automatically provisioned accounts
72
- await near.call("contract.test.near", "method", {})
73
-
74
- await sandbox.stop()
75
- ```
76
-
77
- For testnet/mainnet development, pass a private key directly:
78
-
79
- ```typescript
80
- const near = new Near({
81
- network: "testnet",
82
- privateKey: "ed25519:...",
83
- defaultSignerId: "alice.testnet",
84
- })
85
- ```
86
-
87
- For production applications, use a keyStore:
88
-
89
- ```typescript
90
- import { FileKeyStore } from "near-kit"
91
-
92
- const near = new Near({
93
- network: "testnet",
94
- keyStore: new FileKeyStore("~/.near-credentials"),
95
- })
96
- ```
97
-
98
- ### Frontend & Wallets
99
-
100
- In the browser, connect to user wallets. The same `near.call()`, `near.send()`, and `near.transaction()` methods work seamlessly:
101
-
102
- ```typescript
103
- import { fromWalletSelector } from "near-kit"
104
-
105
- const near = new Near({
106
- network: "testnet",
107
- wallet: fromWalletSelector(walletInstance),
108
- })
109
-
110
- // Same API as backend
111
- await near.call("contract.near", "method", { arg: "value" })
112
- ```
113
-
114
- This works through a signer abstraction - whether you pass `privateKey`, `keyStore`, `wallet`, or `sandbox`, they all implement the same signing interface internally.
115
-
116
- ## Core API
117
-
118
- ### Initialization
119
-
120
- ```typescript
121
- // Simple - defaults to mainnet
122
- const near = new Near()
123
-
124
- // With network selection
125
- const near = new Near({ network: "testnet" })
126
-
127
- // With custom configuration
128
- const near = new Near({
129
- network: "testnet",
130
- privateKey: "ed25519:...",
131
- })
132
- ```
133
-
134
- ### Basic Operations
135
-
136
- ```typescript
137
- // View methods (free, no signature required)
138
- const result = await near.view("contract.near", "get_data", { key: "value" })
139
-
140
- // Check account balance
141
- const balance = await near.getBalance("alice.near")
142
-
143
- // Check if account exists
144
- const exists = await near.accountExists("alice.near")
145
-
146
- // Get network status
147
- const status = await near.getStatus()
148
- ```
149
-
150
- ### Type-Safe Contracts
151
-
152
- ```typescript
153
- import type { Contract } from "near-kit"
154
-
155
- // Define contract interface using Contract<> helper
156
- type MyContract = Contract<{
157
- view: {
158
- get_balance: (args: { account_id: string }) => Promise<string>
159
- get_info: () => Promise<{ name: string; version: string }>
160
- }
161
- call: {
162
- // Just define args - options parameter automatically added!
163
- transfer: (args: { to: string; amount: string }) => Promise<void>
164
- }
165
- }>
166
-
167
- // Create type-safe contract
168
- const contract = near.contract<MyContract>("example.near")
169
-
170
- // Fully typed method calls
171
- const balance = await contract.view.get_balance({ account_id: "alice.near" })
172
- const info = await contract.view.get_info()
173
-
174
- // Call methods automatically get options parameter
175
- await contract.call.transfer(
176
- { to: "bob.near", amount: "10" },
177
- { attachedDeposit: "1 NEAR" }
178
- )
179
- ```
180
-
181
- ### Transaction Builder
182
-
183
- ```typescript
184
- // Alice builds a transaction with multiple actions
185
- // 'alice.near' is the signer - the account that signs and pays for this transaction
186
- const receipt = await near
187
- .transaction("alice.near") // Alice signs
188
- .transfer("bob.near", "10 NEAR") // Alice sends Bob 10 NEAR
189
- .functionCall(
190
- "market.near",
191
- "buy",
192
- { id: "123" },
193
- { attachedDeposit: "5 NEAR" } // Alice attaches 5 NEAR to the call
194
- )
195
- .send()
196
- ```
197
-
198
- ### Batch Operations
199
-
200
- ```typescript
201
- // Run multiple operations in parallel
202
- const [balance, status, exists] = await near.batch(
203
- near.getBalance("alice.near"),
204
- near.getStatus(),
205
- near.accountExists("bob.near")
206
- )
207
- ```
208
-
209
- ## Local Testing with Sandbox
210
-
211
- ```typescript
212
- import { Sandbox } from "near-kit"
213
-
214
- const sandbox = await Sandbox.start()
215
- const near = new Near({ network: sandbox })
216
- // ... run tests
217
- await sandbox.stop()
218
- ```
219
-
220
- **With test framework:**
221
-
222
- ```typescript
223
- let sandbox: Sandbox
224
- beforeAll(async () => {
225
- sandbox = await Sandbox.start()
226
- })
227
- afterAll(async () => {
228
- await sandbox.stop()
229
- })
230
- ```
231
-
232
- ## Key Management
233
-
234
- ```typescript
235
- import { InMemoryKeyStore, FileKeyStore, RotatingKeyStore } from "near-kit"
236
-
237
- // In-memory (runtime only)
238
- const near = new Near({
239
- keyStore: new InMemoryKeyStore({
240
- "alice.near": "ed25519:...",
241
- }),
242
- })
243
-
244
- // File-based (persistent)
245
- const near = new Near({
246
- keyStore: new FileKeyStore("~/.near-credentials"),
247
- })
248
-
249
- // Rotating keys for high-throughput concurrent transactions
250
- const near = new Near({
251
- keyStore: new RotatingKeyStore({
252
- "alice.near": ["ed25519:key1...", "ed25519:key2...", "ed25519:key3..."],
253
- }),
254
- })
255
- ```
256
-
257
- ## Wallet Integration
258
-
259
- near-kit integrates with Wallet Selector and HOT Connector through a signer abstraction. Wallet adapters are converted to signers via `fromWalletSelector()` and `fromHotConnect()` shims, allowing the same API to work across backend and frontend without separate client implementations.
260
-
261
- ### NEAR Wallet Selector
262
-
263
- ```typescript
264
- import { Near, fromWalletSelector } from "near-kit"
265
- import { setupWalletSelector } from "@near-wallet-selector/core"
266
- import { setupMyNearWallet } from "@near-wallet-selector/my-near-wallet"
267
- import { setupHereWallet } from "@near-wallet-selector/here-wallet"
268
-
269
- // Setup wallet selector
270
- const selector = await setupWalletSelector({
271
- network: "testnet",
272
- modules: [setupMyNearWallet(), setupHereWallet()],
273
- })
274
-
275
- // Get wallet instance (after user connects)
276
- const wallet = await selector.wallet()
277
-
278
- // Use with near-kit
279
- const near = new Near({
280
- network: "testnet",
281
- wallet: fromWalletSelector(wallet),
282
- })
283
-
284
- // All operations now use the wallet for signing
285
- await near.call("contract.near", "method", { arg: "value" })
286
- await near.send("bob.near", "10 NEAR")
287
- ```
288
-
289
- ### HOT Connector
290
-
291
- ```typescript
292
- import { Near, fromHotConnect } from "near-kit"
293
- import { NearConnector } from "@hot-labs/near-connect"
294
-
295
- // Create connector
296
- const connector = new NearConnector({ network: "testnet" })
297
-
298
- // Wait for user to connect
299
- connector.on("wallet:signIn", async () => {
300
- const near = new Near({
301
- network: "testnet",
302
- wallet: fromHotConnect(connector),
303
- })
304
-
305
- // Use near-kit with the connected wallet
306
- await near.call("contract.near", "method", { arg: "value" })
307
- })
308
-
309
- // Trigger wallet connection
310
- await connector.signIn()
311
- ```
312
-
313
- ## Error Handling
314
-
315
- Errors are organized by category and include detailed context for debugging. Use `instanceof` checks to handle specific error types.
316
-
317
- #### Network Errors
318
-
319
- ```typescript
320
- import { NetworkError, TimeoutError } from "near-kit"
321
-
322
- try {
323
- await near.call("contract.near", "method", {})
324
- } catch (error) {
325
- if (error instanceof TimeoutError) {
326
- console.log("Request timed out - already retried automatically")
327
- } else if (error instanceof NetworkError) {
328
- // Handle other network issues
329
- }
330
- }
331
- ```
332
-
333
- #### Transaction Errors
334
-
335
- ```typescript
336
- import { InsufficientBalanceError, InvalidNonceError } from "near-kit"
337
-
338
- try {
339
- await near.send("bob.near", "1000000 NEAR")
340
- } catch (error) {
341
- if (error instanceof InsufficientBalanceError) {
342
- console.log(`Need ${error.required}, have ${error.available}`)
343
- } else if (error instanceof InvalidNonceError) {
344
- // Already retried automatically - only thrown if retries exhausted
345
- }
346
- }
347
- ```
348
-
349
- #### Contract Errors
350
-
351
- ```typescript
352
- import { FunctionCallError } from "near-kit"
353
-
354
- try {
355
- await near.call("contract.near", "method", {})
356
- } catch (error) {
357
- if (error instanceof FunctionCallError) {
358
- console.log(`Contract panicked: ${error.panic}`)
359
- console.log(`Logs:`, error.logs)
360
- }
361
- }
362
- ```
363
-
364
- ## Advanced Features
365
-
366
- ### Batch Actions (Multi-Action Transactions)
367
-
368
- Deploy and initialize a contract in a single transaction:
369
-
370
- ```typescript
371
- const contractWasm = await fs.readFile("./contract.wasm")
372
-
373
- await near
374
- .transaction("alice.near")
375
- .createAccount("contract.alice.near")
376
- .transfer("contract.alice.near", "10 NEAR")
377
- .deployContract("contract.alice.near", contractWasm)
378
- .functionCall("contract.alice.near", "init", { owner: "alice.near" })
379
- .send()
380
- ```
381
-
382
- ### NEP-413 Message Signing
383
-
384
- Authenticate users without gas fees:
385
-
386
- ```typescript
387
- const signedMessage = await near.signMessage({
388
- message: "Login to MyApp",
389
- recipient: "myapp.near",
390
- nonce: crypto.getRandomValues(new Uint8Array(32)),
391
- })
392
-
393
- // Send to backend for verification
394
- await fetch("/api/auth", {
395
- method: "POST",
396
- body: JSON.stringify(signedMessage),
397
- })
398
- ```
399
-
400
- ### Delegate Actions (NEP-366)
401
-
402
- Enable meta-transactions and sponsored transactions where a relayer pays the gas:
403
-
404
- ```typescript
405
- import { decodeSignedDelegateAction, Near } from "near-kit"
406
-
407
- // User creates and signs a delegate action (no gas cost to user)
408
- const userNear = new Near({
409
- network: "testnet",
410
- privateKey: "ed25519:...", // User's key
411
- })
412
-
413
- const { signedDelegateAction, payload } = await userNear
414
- .transaction("user.near")
415
- .transfer("recipient.near", "1 NEAR")
416
- .delegate({ blockHeightOffset: 100 })
417
-
418
- // Relayer submits the transaction (pays the gas)
419
- const relayerNear = new Near({
420
- network: "testnet",
421
- privateKey: "ed25519:...", // Relayer's key
422
- })
423
-
424
- await relayerNear
425
- .transaction("relayer.near")
426
- .signedDelegateAction(decodeSignedDelegateAction(payload))
427
- .send()
428
- ```
429
-
430
- ### Automatic Nonce Management
431
-
432
- No more nonce conflicts - the library handles nonce tracking and retries automatically:
433
-
434
- ```typescript
435
- // Safe to run multiple transactions concurrently
436
- await Promise.all([
437
- near.send("bob.near", "1 NEAR"),
438
- near.send("charlie.near", "1 NEAR"),
439
- near.send("dave.near", "1 NEAR"),
440
- ])
441
- // Nonces are automatically managed and conflicts are retried
442
- ```
443
-
444
- For high-throughput scenarios (trading bots, faucets, relayers), use `RotatingKeyStore` with multiple access keys per account:
445
-
446
- ```typescript
447
- import { RotatingKeyStore } from "near-kit"
448
-
449
- const keyStore = new RotatingKeyStore({
450
- "bot.near": ["ed25519:key1...", "ed25519:key2...", "ed25519:key3..."],
451
- })
452
-
453
- const near = new Near({ keyStore })
454
-
455
- // Send 20 concurrent transactions - each key handles its own nonce
456
- await Promise.all(
457
- Array(20)
458
- .fill(0)
459
- .map(() => near.send("recipient.near", "0.1 NEAR"))
460
- )
461
- ```
462
-
463
- ### Smart Retry Logic
464
-
465
- Automatic retries for network errors with exponential backoff:
466
-
467
- ```typescript
468
- try {
469
- await near.call("contract.near", "method", {})
470
- } catch (error) {
471
- if (error instanceof TimeoutError && error.retryable) {
472
- // Already retried automatically
473
- }
474
- }
475
- ```
476
-
477
- ## Development
478
-
479
- ```bash
480
- # Install dependencies
481
- bun install
482
-
483
- # Run tests
484
- bun test
485
-
486
- # Build
487
- bun run build
488
-
489
- # Run examples
490
- bun run examples/quickstart.ts
491
- ```
492
-
493
- ## License
494
-
495
- MIT