@fastnear/api 0.1.0 → 0.3.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.
Files changed (44) hide show
  1. package/dist/cjs/cryptoUtils.js +89 -0
  2. package/dist/cjs/cryptoUtils.js.map +7 -0
  3. package/dist/cjs/index.esm.js +1191 -0
  4. package/dist/cjs/index.esm.js.map +7 -0
  5. package/dist/cjs/index.js +1246 -0
  6. package/dist/cjs/index.js.map +7 -0
  7. package/dist/cjs/near.js +1191 -0
  8. package/dist/cjs/near.js.map +7 -0
  9. package/dist/cjs/transaction.js +360 -0
  10. package/dist/cjs/transaction.js.map +7 -0
  11. package/dist/cjs/utils.js +105 -0
  12. package/dist/cjs/utils.js.map +7 -0
  13. package/dist/esm/chunk-2SCAGR3F.js +68 -0
  14. package/dist/esm/chunk-2SCAGR3F.js.map +7 -0
  15. package/dist/esm/chunk-B2HMQPYI.js +814 -0
  16. package/dist/esm/chunk-B2HMQPYI.js.map +7 -0
  17. package/dist/esm/chunk-S5Q2EM2B.js +48 -0
  18. package/dist/esm/chunk-S5Q2EM2B.js.map +7 -0
  19. package/{src/transaction.js → dist/esm/chunk-YKPILPMX.js} +113 -99
  20. package/dist/esm/chunk-YKPILPMX.js.map +7 -0
  21. package/dist/esm/cryptoUtils.js +21 -0
  22. package/dist/esm/cryptoUtils.js.map +7 -0
  23. package/dist/esm/index.esm.js +13 -0
  24. package/dist/esm/index.esm.js.map +7 -0
  25. package/dist/esm/index.js +63 -0
  26. package/dist/esm/index.js.map +7 -0
  27. package/dist/esm/near.js +15 -0
  28. package/dist/esm/near.js.map +7 -0
  29. package/dist/esm/transaction.js +16 -0
  30. package/dist/esm/transaction.js.map +7 -0
  31. package/dist/esm/utils.js +24 -0
  32. package/dist/esm/utils.js.map +7 -0
  33. package/dist/umd/index.js +4199 -0
  34. package/dist/umd/index.js.map +7 -0
  35. package/package.json +33 -25
  36. package/README.md +0 -76
  37. package/dist/fastnear.cjs +0 -35
  38. package/dist/fastnear.ejs +0 -24
  39. package/dist/fastnear.js +0 -35
  40. package/src/crypto.js +0 -37
  41. package/src/index.esm.js +0 -3
  42. package/src/index.js +0 -8
  43. package/src/near.js +0 -566
  44. package/src/utils.js +0 -48
@@ -0,0 +1,1191 @@
1
+ /* ⋈ 🏃🏻💨 FastNEAR API - https://github.com/fastnear */
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.esm.ts
31
+ var index_esm_exports = {};
32
+ __export(index_esm_exports, {
33
+ $$: () => convertUnit,
34
+ near: () => api
35
+ });
36
+ module.exports = __toCommonJS(index_esm_exports);
37
+
38
+ // src/near.ts
39
+ var import_big2 = __toESM(require("big.js"), 1);
40
+
41
+ // ../wallet-adapter/src/index.ts
42
+ var WalletAdapter = class _WalletAdapter {
43
+ /** @type {HTMLIFrameElement} */
44
+ #iframe = null;
45
+ /** @type {string} */
46
+ #targetOrigin;
47
+ /** @type {string} */
48
+ #widgetUrl;
49
+ /** @type {Map<string, Function>} */
50
+ #pending = /* @__PURE__ */ new Map();
51
+ /** @type {WalletState} */
52
+ #state;
53
+ /** @type {Function} */
54
+ #onStateUpdate;
55
+ /** @type {string} */
56
+ #callbackUrl;
57
+ /** @type {string} */
58
+ static defaultWidgetUrl = "https://wallet-adapter.fastnear.com";
59
+ /**
60
+ * @param {WalletAdapterConfig} [config]
61
+ */
62
+ constructor({
63
+ widgetUrl = _WalletAdapter.defaultWidgetUrl,
64
+ targetOrigin = "*",
65
+ onStateUpdate,
66
+ lastState,
67
+ callbackUrl = window.location.href
68
+ } = {}) {
69
+ this.#targetOrigin = targetOrigin;
70
+ this.#widgetUrl = widgetUrl;
71
+ this.#onStateUpdate = onStateUpdate;
72
+ this.#callbackUrl = callbackUrl;
73
+ this.#state = lastState || {};
74
+ window.addEventListener("message", this.#handleMessage.bind(this));
75
+ }
76
+ /**
77
+ * Creates an iframe for wallet interaction
78
+ * @param {string} path - Path to load in iframe
79
+ * @returns {HTMLIFrameElement}
80
+ */
81
+ #createIframe(path) {
82
+ if (this.#iframe) {
83
+ this.#iframe.remove();
84
+ }
85
+ const url = new URL(path, this.#widgetUrl);
86
+ const iframe = document.createElement("iframe");
87
+ iframe.src = url.toString();
88
+ iframe.allow = "usb";
89
+ iframe.style.border = "none";
90
+ iframe.style.zIndex = "10000";
91
+ iframe.style.position = "fixed";
92
+ iframe.style.display = "block";
93
+ iframe.style.top = "0";
94
+ iframe.style.left = "0";
95
+ iframe.style.width = "100%";
96
+ iframe.style.height = "100%";
97
+ document.body.appendChild(iframe);
98
+ this.#iframe = iframe;
99
+ return iframe;
100
+ }
101
+ /**
102
+ * Handles messages from the wallet widget
103
+ * @param {MessageEvent} event
104
+ */
105
+ #handleMessage(event) {
106
+ if (this.#targetOrigin !== "*" && event.origin !== this.#targetOrigin) {
107
+ return;
108
+ }
109
+ const { id, type, action, payload } = event.data;
110
+ if (type !== "wallet-adapter") return;
111
+ if (action === "close") {
112
+ this.#iframe?.remove();
113
+ this.#iframe = null;
114
+ return;
115
+ }
116
+ if (payload?.state) {
117
+ this.#state = { ...this.#state, ...payload.state };
118
+ this.#onStateUpdate?.(this.#state);
119
+ }
120
+ const resolve = this.#pending.get(id);
121
+ if (resolve) {
122
+ this.#pending.delete(id);
123
+ this.#iframe?.remove();
124
+ this.#iframe = null;
125
+ resolve(payload);
126
+ }
127
+ }
128
+ /**
129
+ * Sends a message to the wallet widget
130
+ * @param {string} path - Path to load in iframe
131
+ * @param {string} method - Method to call
132
+ * @param {Object} params - Parameters to pass
133
+ * @returns {Promise<any>}
134
+ */
135
+ async #sendMessage(path, method, params) {
136
+ return new Promise((resolve) => {
137
+ const id = Math.random().toString(36).slice(2);
138
+ this.#pending.set(id, resolve);
139
+ const iframe = this.#createIframe(path);
140
+ iframe.onload = () => {
141
+ iframe.contentWindow?.postMessage(
142
+ {
143
+ type: "wallet-adapter",
144
+ method,
145
+ params: {
146
+ id,
147
+ ...params,
148
+ state: this.#state,
149
+ callbackUrl: params.callbackUrl || this.#callbackUrl
150
+ }
151
+ },
152
+ this.#targetOrigin
153
+ );
154
+ };
155
+ });
156
+ }
157
+ /**
158
+ * Get current wallet state
159
+ * @returns {WalletState}
160
+ */
161
+ getState() {
162
+ return { ...this.#state };
163
+ }
164
+ /**
165
+ * Set current wallet state
166
+ * @param state
167
+ */
168
+ setState(state) {
169
+ this.#state = state;
170
+ }
171
+ /**
172
+ * Sign in with a NEAR wallet
173
+ * @param {SignInConfig} config
174
+ * @returns {Promise<SignInResult>}
175
+ */
176
+ async signIn(config) {
177
+ return this.#sendMessage("/login.html", "signIn", config);
178
+ }
179
+ /**
180
+ * Send a transaction using connected wallet
181
+ * @param {TransactionConfig} config
182
+ * @returns {Promise<TransactionResult>}
183
+ */
184
+ async sendTransactions(config) {
185
+ return this.#sendMessage("/send.html", "sendTransactions", config);
186
+ }
187
+ /**
188
+ * Clean up adapter resources
189
+ */
190
+ destroy() {
191
+ window.removeEventListener("message", this.#handleMessage);
192
+ this.#iframe?.remove();
193
+ this.#iframe = null;
194
+ }
195
+ };
196
+
197
+ // src/cryptoUtils.ts
198
+ var import_ed25519 = require("@noble/curves/ed25519");
199
+ var import_sha2 = require("@noble/hashes/sha2");
200
+
201
+ // src/utils.ts
202
+ var import_base58_js = require("base58-js");
203
+ var import_big = __toESM(require("big.js"), 1);
204
+ var import_js_base64 = require("js-base64");
205
+ var LsPrefix = "__fastnear_";
206
+ function toBase64(data) {
207
+ if (typeof data === "string") {
208
+ return (0, import_js_base64.encode)(data);
209
+ } else {
210
+ const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
211
+ const str = String.fromCharCode(...bytes);
212
+ return (0, import_js_base64.encode)(str);
213
+ }
214
+ }
215
+ function fromBase64(str) {
216
+ const binaryString = (0, import_js_base64.decode)(str);
217
+ const len = binaryString.length;
218
+ const bytes = new Uint8Array(len);
219
+ for (let i = 0; i < len; i++) {
220
+ bytes[i] = binaryString.charCodeAt(i);
221
+ }
222
+ return bytes;
223
+ }
224
+ function lsSet(key, value) {
225
+ if (value === null || value === void 0) {
226
+ localStorage.removeItem(LsPrefix + key);
227
+ } else {
228
+ localStorage.setItem(LsPrefix + key, JSON.stringify(value));
229
+ }
230
+ }
231
+ function lsGet(key) {
232
+ const value = localStorage.getItem(LsPrefix + key);
233
+ return tryParseJson(value, null);
234
+ }
235
+ function tryParseJson(...args) {
236
+ try {
237
+ return JSON.parse(args[0]);
238
+ } catch {
239
+ if (args.length > 1) {
240
+ return args[1];
241
+ }
242
+ return args[0];
243
+ }
244
+ }
245
+ function canSignWithLAK(actions) {
246
+ return actions.length === 1 && actions[0].type === "FunctionCall" && (0, import_big.default)(actions[0]?.deposit ?? "0").eq(0);
247
+ }
248
+
249
+ // src/cryptoUtils.ts
250
+ var keyFromString = (key) => (0, import_base58_js.base58_to_binary)(
251
+ key.includes(":") ? (() => {
252
+ const [curve, keyPart] = key.split(":");
253
+ if (curve !== "ed25519") {
254
+ throw new Error(`Unsupported curve: ${curve}`);
255
+ }
256
+ return keyPart;
257
+ })() : key
258
+ );
259
+ var keyToString = (key) => `ed25519:${(0, import_base58_js.binary_to_base58)(key)}`;
260
+ function publicKeyFromPrivate(privateKey) {
261
+ privateKey = keyFromString(privateKey).slice(0, 32);
262
+ const publicKey = import_ed25519.ed25519.getPublicKey(privateKey);
263
+ return keyToString(publicKey);
264
+ }
265
+ function privateKeyFromRandom() {
266
+ const privateKey = crypto.getRandomValues(new Uint8Array(64));
267
+ return keyToString(privateKey);
268
+ }
269
+ function signHash(hash, privateKey) {
270
+ privateKey = keyFromString(privateKey).slice(0, 32);
271
+ const signature = import_ed25519.ed25519.sign((0, import_base58_js.base58_to_binary)(hash), privateKey);
272
+ return (0, import_base58_js.binary_to_base58)(signature);
273
+ }
274
+
275
+ // src/transaction.ts
276
+ var import_borsh = require("borsh");
277
+ function mapTransaction(jsonTransaction) {
278
+ return {
279
+ signerId: jsonTransaction.signerId,
280
+ publicKey: {
281
+ ed25519Key: {
282
+ data: keyFromString(jsonTransaction.publicKey)
283
+ }
284
+ },
285
+ nonce: BigInt(jsonTransaction.nonce),
286
+ receiverId: jsonTransaction.receiverId,
287
+ blockHash: (0, import_base58_js.base58_to_binary)(jsonTransaction.blockHash),
288
+ actions: jsonTransaction.actions.map(mapAction)
289
+ };
290
+ }
291
+ function serializeTransaction(jsonTransaction) {
292
+ const transaction = mapTransaction(jsonTransaction);
293
+ return (0, import_borsh.serialize)(SCHEMA.Transaction, transaction);
294
+ }
295
+ function serializeSignedTransaction(jsonTransaction, signature) {
296
+ const signedTransaction = {
297
+ transaction: mapTransaction(jsonTransaction),
298
+ signature: {
299
+ ed25519Signature: {
300
+ data: (0, import_base58_js.base58_to_binary)(signature)
301
+ }
302
+ }
303
+ };
304
+ return (0, import_borsh.serialize)(SCHEMA.SignedTransaction, signedTransaction);
305
+ }
306
+ function mapAction(action) {
307
+ switch (action.type) {
308
+ case "CreateAccount": {
309
+ return {
310
+ createAccount: {}
311
+ };
312
+ }
313
+ case "DeployContract": {
314
+ return {
315
+ deployContract: {
316
+ code: fromBase64(action.codeBase64)
317
+ }
318
+ };
319
+ }
320
+ case "FunctionCall": {
321
+ return {
322
+ functionCall: {
323
+ methodName: action.methodName,
324
+ args: action.argsBase64 ? fromBase64(action.argsBase64) : new TextEncoder().encode(JSON.stringify(action.args)),
325
+ gas: BigInt(action.gas),
326
+ deposit: BigInt(action.deposit)
327
+ }
328
+ };
329
+ }
330
+ case "Transfer": {
331
+ return {
332
+ transfer: {
333
+ deposit: BigInt(action.deposit)
334
+ }
335
+ };
336
+ }
337
+ case "Stake": {
338
+ return {
339
+ stake: {
340
+ stake: BigInt(action.stake),
341
+ publicKey: {
342
+ ed25519Key: {
343
+ data: keyFromString(action.publicKey)
344
+ }
345
+ }
346
+ }
347
+ };
348
+ }
349
+ case "AddKey": {
350
+ return {
351
+ addKey: {
352
+ publicKey: {
353
+ ed25519Key: {
354
+ data: keyFromString(action.publicKey)
355
+ }
356
+ },
357
+ accessKey: {
358
+ nonce: BigInt(action.accessKey.nonce),
359
+ permission: action.accessKey.permission === "FullAccess" ? { fullAccess: {} } : {
360
+ functionCall: {
361
+ allowance: action.accessKey.allowance ? BigInt(action.accessKey.allowance) : null,
362
+ receiverId: action.accessKey.receiverId,
363
+ methodNames: action.accessKey.methodNames
364
+ }
365
+ }
366
+ }
367
+ }
368
+ };
369
+ }
370
+ case "DeleteKey": {
371
+ return {
372
+ deleteKey: {
373
+ publicKey: {
374
+ ed25519Key: {
375
+ data: keyFromString(action.publicKey)
376
+ }
377
+ }
378
+ }
379
+ };
380
+ }
381
+ case "DeleteAccount": {
382
+ return {
383
+ deleteAccount: {
384
+ beneficiaryId: action.beneficiaryId
385
+ }
386
+ };
387
+ }
388
+ case "SignedDelegate": {
389
+ return {
390
+ signedDelegate: {
391
+ delegateAction: mapAction(action.delegateAction),
392
+ signature: {
393
+ ed25519Signature: (0, import_base58_js.base58_to_binary)(action.signature)
394
+ }
395
+ }
396
+ };
397
+ }
398
+ default: {
399
+ throw new Error("Not implemented action: " + action.type);
400
+ }
401
+ }
402
+ }
403
+ var SCHEMA = new class BorshSchema {
404
+ Ed25519Signature = {
405
+ struct: {
406
+ data: { array: { type: "u8", len: 64 } }
407
+ }
408
+ };
409
+ Secp256k1Signature = {
410
+ struct: {
411
+ data: { array: { type: "u8", len: 65 } }
412
+ }
413
+ };
414
+ Signature = {
415
+ enum: [
416
+ { struct: { ed25519Signature: this.Ed25519Signature } },
417
+ { struct: { secp256k1Signature: this.Secp256k1Signature } }
418
+ ]
419
+ };
420
+ Ed25519Data = {
421
+ struct: {
422
+ data: { array: { type: "u8", len: 32 } }
423
+ }
424
+ };
425
+ Secp256k1Data = {
426
+ struct: {
427
+ data: { array: { type: "u8", len: 64 } }
428
+ }
429
+ };
430
+ PublicKey = {
431
+ enum: [
432
+ { struct: { ed25519Key: this.Ed25519Data } },
433
+ { struct: { secp256k1Key: this.Secp256k1Data } }
434
+ ]
435
+ };
436
+ FunctionCallPermission = {
437
+ struct: {
438
+ allowance: { option: "u128" },
439
+ receiverId: "string",
440
+ methodNames: { array: { type: "string" } }
441
+ }
442
+ };
443
+ FullAccessPermission = {
444
+ struct: {}
445
+ };
446
+ AccessKeyPermission = {
447
+ enum: [
448
+ { struct: { functionCall: this.FunctionCallPermission } },
449
+ { struct: { fullAccess: this.FullAccessPermission } }
450
+ ]
451
+ };
452
+ AccessKey = {
453
+ struct: {
454
+ nonce: "u64",
455
+ permission: this.AccessKeyPermission
456
+ }
457
+ };
458
+ CreateAccount = {
459
+ struct: {}
460
+ };
461
+ DeployContract = {
462
+ struct: {
463
+ code: { array: { type: "u8" } }
464
+ }
465
+ };
466
+ FunctionCall = {
467
+ struct: {
468
+ methodName: "string",
469
+ args: { array: { type: "u8" } },
470
+ gas: "u64",
471
+ deposit: "u128"
472
+ }
473
+ };
474
+ Transfer = {
475
+ struct: {
476
+ deposit: "u128"
477
+ }
478
+ };
479
+ Stake = {
480
+ struct: {
481
+ stake: "u128",
482
+ publicKey: this.PublicKey
483
+ }
484
+ };
485
+ AddKey = {
486
+ struct: {
487
+ publicKey: this.PublicKey,
488
+ accessKey: this.AccessKey
489
+ }
490
+ };
491
+ DeleteKey = {
492
+ struct: {
493
+ publicKey: this.PublicKey
494
+ }
495
+ };
496
+ DeleteAccount = {
497
+ struct: {
498
+ beneficiaryId: "string"
499
+ }
500
+ };
501
+ ClassicAction = {
502
+ enum: [
503
+ { struct: { createAccount: this.CreateAccount } },
504
+ { struct: { deployContract: this.DeployContract } },
505
+ { struct: { functionCall: this.FunctionCall } },
506
+ { struct: { transfer: this.Transfer } },
507
+ { struct: { stake: this.Stake } },
508
+ { struct: { addKey: this.AddKey } },
509
+ { struct: { deleteKey: this.DeleteKey } },
510
+ { struct: { deleteAccount: this.DeleteAccount } }
511
+ ]
512
+ };
513
+ DelegateAction = {
514
+ struct: {
515
+ senderId: "string",
516
+ receiverId: "string",
517
+ actions: { array: { type: this.ClassicAction } },
518
+ nonce: "u64",
519
+ maxBlockHeight: "u64",
520
+ publicKey: this.PublicKey
521
+ }
522
+ };
523
+ SignedDelegate = {
524
+ struct: {
525
+ delegateAction: this.DelegateAction,
526
+ signature: this.Signature
527
+ }
528
+ };
529
+ Action = {
530
+ enum: [
531
+ { struct: { createAccount: this.CreateAccount } },
532
+ { struct: { deployContract: this.DeployContract } },
533
+ { struct: { functionCall: this.FunctionCall } },
534
+ { struct: { transfer: this.Transfer } },
535
+ { struct: { stake: this.Stake } },
536
+ { struct: { addKey: this.AddKey } },
537
+ { struct: { deleteKey: this.DeleteKey } },
538
+ { struct: { deleteAccount: this.DeleteAccount } },
539
+ { struct: { signedDelegate: this.SignedDelegate } }
540
+ ]
541
+ };
542
+ Transaction = {
543
+ struct: {
544
+ signerId: "string",
545
+ publicKey: this.PublicKey,
546
+ nonce: "u64",
547
+ receiverId: "string",
548
+ blockHash: { array: { type: "u8", len: 32 } },
549
+ actions: { array: { type: this.Action } }
550
+ }
551
+ };
552
+ SignedTransaction = {
553
+ struct: {
554
+ transaction: this.Transaction,
555
+ signature: this.Signature
556
+ }
557
+ };
558
+ }();
559
+
560
+ // src/near.ts
561
+ import_big2.default.DP = 27;
562
+ var MaxBlockDelayMs = 1e3 * 60 * 60 * 6;
563
+ var WIDGET_URL = "http://localhost:3000/";
564
+ var DEFAULT_NETWORK_ID = "mainnet";
565
+ var NETWORKS = {
566
+ testnet: {
567
+ networkId: "testnet",
568
+ nodeUrl: "https://rpc.testnet.fastnear.com/"
569
+ },
570
+ mainnet: {
571
+ networkId: "mainnet",
572
+ nodeUrl: "https://rpc.mainnet.fastnear.com/"
573
+ }
574
+ };
575
+ var _config = lsGet("config") || { ...NETWORKS[DEFAULT_NETWORK_ID] };
576
+ var _state = lsGet("state") || {};
577
+ try {
578
+ _state.publicKey = _state.privateKey ? publicKeyFromPrivate(_state.privateKey) : null;
579
+ } catch (e) {
580
+ console.error("Error parsing private key:", e);
581
+ _state.privateKey = null;
582
+ lsSet("nonce", null);
583
+ }
584
+ var _txHistory = lsGet("txHistory") || {};
585
+ var _eventListeners = {
586
+ account: /* @__PURE__ */ new Set(),
587
+ tx: /* @__PURE__ */ new Set()
588
+ };
589
+ var _unbroadcastedEvents = {
590
+ account: [],
591
+ tx: []
592
+ };
593
+ function getWalletAdapterState() {
594
+ return {
595
+ publicKey: _state.publicKey,
596
+ accountId: _state.accountId,
597
+ lastWalletId: _state.lastWalletId,
598
+ networkId: DEFAULT_NETWORK_ID
599
+ };
600
+ }
601
+ var _adapter;
602
+ function updateState(newState) {
603
+ const oldState = _state;
604
+ _state = { ..._state, ...newState };
605
+ lsSet("state", {
606
+ accountId: _state.accountId,
607
+ privateKey: _state.privateKey,
608
+ lastWalletId: _state.lastWalletId,
609
+ accessKeyContractId: _state.accessKeyContractId
610
+ });
611
+ if (newState.hasOwnProperty("privateKey") && newState.privateKey !== oldState.privateKey) {
612
+ _state.publicKey = newState.privateKey ? publicKeyFromPrivate(newState.privateKey) : null;
613
+ lsSet("nonce", null);
614
+ }
615
+ if (newState.accountId !== oldState.accountId) {
616
+ notifyAccountListeners(newState.accountId);
617
+ }
618
+ if (newState.hasOwnProperty("lastWalletId") && newState.lastWalletId !== oldState.lastWalletId || newState.hasOwnProperty("accountId") && newState.accountId !== oldState.accountId || newState.hasOwnProperty("privateKey") && newState.privateKey !== oldState.privateKey) {
619
+ _adapter.setState(getWalletAdapterState());
620
+ }
621
+ }
622
+ function updateTxHistory(txStatus) {
623
+ const txId = txStatus.txId;
624
+ _txHistory[txId] = {
625
+ ..._txHistory[txId] ?? {},
626
+ ...txStatus,
627
+ updateTimestamp: Date.now()
628
+ };
629
+ lsSet("txHistory", _txHistory);
630
+ notifyTxListeners(_txHistory[txId]);
631
+ }
632
+ function onAdapterStateUpdate(state) {
633
+ console.log("Adapter state update:", state);
634
+ const { accountId, lastWalletId, privateKey } = state;
635
+ updateState({
636
+ accountId,
637
+ lastWalletId,
638
+ ...privateKey && { privateKey }
639
+ });
640
+ }
641
+ _adapter = new WalletAdapter({
642
+ onStateUpdate: onAdapterStateUpdate,
643
+ lastState: getWalletAdapterState(),
644
+ widgetUrl: WIDGET_URL
645
+ });
646
+ function parseJsonFromBytes(bytes) {
647
+ try {
648
+ const decoder = new TextDecoder();
649
+ return JSON.parse(decoder.decode(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)));
650
+ } catch (e) {
651
+ try {
652
+ return bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
653
+ } catch (e2) {
654
+ return bytes;
655
+ }
656
+ }
657
+ }
658
+ function withBlockId(params, blockId) {
659
+ return blockId === "final" || blockId === "optimistic" ? { ...params, finality: blockId } : !!blockId ? { ...params, block_id: blockId } : { ...params, finality: "optimistic" };
660
+ }
661
+ async function queryRpc(method, params) {
662
+ const response = await fetch(_config.nodeUrl, {
663
+ method: "POST",
664
+ headers: { "Content-Type": "application/json" },
665
+ body: JSON.stringify({
666
+ jsonrpc: "2.0",
667
+ id: `fastnear-${Date.now()}`,
668
+ method,
669
+ params
670
+ })
671
+ });
672
+ const result = await response.json();
673
+ if (result.error) {
674
+ throw new Error(JSON.stringify(result.error));
675
+ }
676
+ return result.result;
677
+ }
678
+ function afterTxSent(txId) {
679
+ queryRpc("tx", {
680
+ tx_hash: _txHistory[txId].txHash,
681
+ sender_account_id: _txHistory[txId].tx.signerId,
682
+ wait_until: "EXECUTED_OPTIMISTIC"
683
+ }).then((result) => {
684
+ const successValue = result?.status?.SuccessValue;
685
+ updateTxHistory({
686
+ txId,
687
+ status: "Executed",
688
+ result,
689
+ successValue: successValue ? tryParseJson(fromBase64(successValue)) : void 0,
690
+ finalState: true
691
+ });
692
+ }).catch((error) => {
693
+ updateTxHistory({
694
+ txId,
695
+ status: "ErrorAfterIncluded",
696
+ error: tryParseJson(error.message),
697
+ finalState: true
698
+ });
699
+ });
700
+ }
701
+ function sendTxToRpc(signedTxBase64, waitUntil, txId) {
702
+ queryRpc("send_tx", {
703
+ signed_tx_base64: signedTxBase64,
704
+ wait_until: waitUntil ?? "INCLUDED"
705
+ }).then((result) => {
706
+ console.log("Transaction included:", result);
707
+ updateTxHistory({
708
+ txId,
709
+ status: "Included",
710
+ finalState: false
711
+ });
712
+ afterTxSent(txId);
713
+ }).catch((error) => {
714
+ updateTxHistory({
715
+ txId,
716
+ status: "Error",
717
+ error: tryParseJson(error.message),
718
+ finalState: false
719
+ });
720
+ });
721
+ }
722
+ function notifyAccountListeners(accountId) {
723
+ if (_eventListeners.account.size === 0) {
724
+ _unbroadcastedEvents.account.push(accountId);
725
+ return;
726
+ }
727
+ _eventListeners.account.forEach((callback) => {
728
+ try {
729
+ callback(accountId);
730
+ } catch (e) {
731
+ console.error(e);
732
+ }
733
+ });
734
+ }
735
+ function notifyTxListeners(tx) {
736
+ if (_eventListeners.tx.size === 0) {
737
+ _unbroadcastedEvents.tx.push(tx);
738
+ return;
739
+ }
740
+ _eventListeners.tx.forEach((callback) => {
741
+ try {
742
+ callback(tx);
743
+ } catch (e) {
744
+ console.error(e);
745
+ }
746
+ });
747
+ }
748
+ function convertUnit(s, ...args) {
749
+ if (Array.isArray(s)) {
750
+ s = s.reduce((acc, part, i) => {
751
+ return acc + (args[i - 1] ?? "") + part;
752
+ });
753
+ }
754
+ if (typeof s == "string") {
755
+ let match = s.match(/([0-9.,_]+)\s*([a-zA-Z]+)?/);
756
+ if (match) {
757
+ let amount = match[1].replace(/[_,]/g, "");
758
+ let unitPart = match[2];
759
+ if (unitPart) {
760
+ switch (unitPart.toLowerCase()) {
761
+ case "near":
762
+ return (0, import_big2.default)(amount).mul((0, import_big2.default)(10).pow(24)).toFixed(0);
763
+ case "tgas":
764
+ return (0, import_big2.default)(amount).mul((0, import_big2.default)(10).pow(12)).toFixed(0);
765
+ case "ggas":
766
+ return (0, import_big2.default)(amount).mul((0, import_big2.default)(10).pow(9)).toFixed(0);
767
+ case "gas":
768
+ return (0, import_big2.default)(amount).toFixed(0);
769
+ default:
770
+ throw new Error(`Unknown unit: ${unit}`);
771
+ }
772
+ } else {
773
+ return (0, import_big2.default)(amount).toFixed(0);
774
+ }
775
+ }
776
+ }
777
+ return (0, import_big2.default)(s).toFixed(0);
778
+ }
779
+ var api = {
780
+ // Context
781
+ get accountId() {
782
+ return _state.accountId;
783
+ },
784
+ get publicKey() {
785
+ return _state.publicKey;
786
+ },
787
+ config(newConfig) {
788
+ if (newConfig) {
789
+ if (newConfig.networkId && _config.networkId !== newConfig.networkId) {
790
+ _config = { ...NETWORKS[newConfig.networkId] };
791
+ updateState({
792
+ accountId: null,
793
+ privateKey: null,
794
+ lastWalletId: null
795
+ });
796
+ lsSet("block", null);
797
+ _txHistory = {};
798
+ lsSet("txHistory", _txHistory);
799
+ }
800
+ _config = { ..._config, ...newConfig };
801
+ lsSet("config", _config);
802
+ }
803
+ return _config;
804
+ },
805
+ get authStatus() {
806
+ if (!_state.accountId) {
807
+ return "SignedOut";
808
+ }
809
+ const accessKey = _state.publicKey;
810
+ const contractId = _state.accessKeyContractId;
811
+ if (accessKey && contractId && _state.privateKey) {
812
+ return {
813
+ type: "SignedInWithLimitedAccessKey",
814
+ accessKey,
815
+ contractId
816
+ };
817
+ }
818
+ return "SignedIn";
819
+ },
820
+ // Query Methods
821
+ async view({ contractId, methodName, args, argsBase64, blockId }) {
822
+ const encodedArgs = argsBase64 || (args ? toBase64(JSON.stringify(args)) : "");
823
+ const result = await queryRpc(
824
+ "query",
825
+ withBlockId(
826
+ {
827
+ request_type: "call_function",
828
+ account_id: contractId,
829
+ method_name: methodName,
830
+ args_base64: encodedArgs
831
+ },
832
+ blockId
833
+ )
834
+ );
835
+ return parseJsonFromBytes(result.result);
836
+ },
837
+ async account({ accountId, blockId }) {
838
+ return queryRpc(
839
+ "query",
840
+ withBlockId(
841
+ {
842
+ request_type: "view_account",
843
+ account_id: accountId
844
+ },
845
+ blockId
846
+ )
847
+ );
848
+ },
849
+ async block({ blockId }) {
850
+ return queryRpc("block", withBlockId({}, blockId));
851
+ },
852
+ async accessKey({ accountId, publicKey, blockId }) {
853
+ return queryRpc(
854
+ "query",
855
+ withBlockId(
856
+ {
857
+ request_type: "view_access_key",
858
+ account_id: accountId,
859
+ public_key: publicKey
860
+ },
861
+ blockId
862
+ )
863
+ );
864
+ },
865
+ async tx({ txHash, accountId }) {
866
+ return queryRpc("tx", [txHash, accountId]);
867
+ },
868
+ localTxHistory() {
869
+ return [..._txHistory];
870
+ },
871
+ // Transaction Methods
872
+ async sendTx({ receiverId, actions, waitUntil }) {
873
+ const signerId = _state.accountId;
874
+ if (!signerId) {
875
+ throw new Error("Not signed in");
876
+ }
877
+ const publicKey = _state.publicKey;
878
+ const privateKey = _state.privateKey;
879
+ const txId = `tx-${Date.now()}-${Math.random()}`;
880
+ if (!privateKey || receiverId !== _state.accessKeyContractId || !canSignWithLAK(actions)) {
881
+ const jsonTransaction2 = {
882
+ signerId,
883
+ receiverId,
884
+ actions
885
+ };
886
+ updateTxHistory({
887
+ status: "Pending",
888
+ txId,
889
+ tx: jsonTransaction2,
890
+ finalState: false
891
+ });
892
+ const url = new URL(window.location.href);
893
+ url.searchParams.set("txIds", txId);
894
+ _adapter.sendTransactions({
895
+ transactions: [jsonTransaction2],
896
+ callbackUrl: url.toString()
897
+ }).then((result) => {
898
+ console.log("Transaction result:", result);
899
+ if (result.url) {
900
+ console.log("Redirecting to wallet:", result.url);
901
+ setTimeout(() => {
902
+ window.location.href = result.url;
903
+ }, 100);
904
+ } else if (result.outcomes) {
905
+ result.outcomes.forEach((result2) => {
906
+ updateTxHistory({
907
+ txId,
908
+ status: "Executed",
909
+ result: result2,
910
+ txHash: result2.transaction.hash,
911
+ finalState: true
912
+ });
913
+ });
914
+ } else if (result.rejected) {
915
+ updateTxHistory({
916
+ txId,
917
+ status: "RejectedByUser",
918
+ finalState: true
919
+ });
920
+ } else if (result.error) {
921
+ updateTxHistory({
922
+ txId,
923
+ status: "Error",
924
+ error: tryParseJson(result.error),
925
+ finalState: true
926
+ });
927
+ }
928
+ }).catch((error) => {
929
+ updateTxHistory({
930
+ txId,
931
+ status: "Error",
932
+ error: tryParseJson(error.message),
933
+ finalState: true
934
+ });
935
+ });
936
+ return txId;
937
+ }
938
+ const toDoPromises = {};
939
+ let nonce = lsGet("nonce");
940
+ if (nonce === null || nonce === void 0) {
941
+ toDoPromises.nonce = this.accessKey({
942
+ accountId: signerId,
943
+ publicKey
944
+ }).then((accessKey) => {
945
+ if (accessKey.error) {
946
+ throw new Error(`Access key error: ${accessKey.error}`);
947
+ }
948
+ lsSet("nonce", accessKey.nonce);
949
+ return accessKey.nonce;
950
+ });
951
+ }
952
+ let block = lsGet("block");
953
+ if (!block || parseFloat(block.header.timestamp_nanosec) / 1e6 + MaxBlockDelayMs < Date.now()) {
954
+ toDoPromises.block = this.block({ blockId: "final" }).then((block2) => {
955
+ block2 = {
956
+ header: {
957
+ prev_hash: block2.header.prev_hash,
958
+ timestamp_nanosec: block2.header.timestamp_nanosec
959
+ }
960
+ };
961
+ lsSet("block", block2);
962
+ return block2;
963
+ });
964
+ }
965
+ if (Object.keys(toDoPromises).length > 0) {
966
+ let results = await Promise.all(Object.values(toDoPromises));
967
+ for (let i = 0; i < results.length; i++) {
968
+ if (Object.keys(toDoPromises)[i] === "nonce") {
969
+ nonce = results[i];
970
+ } else if (Object.keys(toDoPromises)[i] === "block") {
971
+ block = results[i];
972
+ }
973
+ }
974
+ }
975
+ const newNonce = nonce + 1;
976
+ lsSet("nonce", newNonce);
977
+ const blockHash = block.header.prev_hash;
978
+ const jsonTransaction = {
979
+ signerId,
980
+ publicKey,
981
+ nonce: newNonce,
982
+ receiverId,
983
+ blockHash,
984
+ actions
985
+ };
986
+ console.log("Transaction:", jsonTransaction);
987
+ const transaction = serializeTransaction(jsonTransaction);
988
+ const txHash = (0, import_base58_js.binary_to_base58)(import_sha2.sha256(transaction));
989
+ const signature = signHash(txHash, privateKey);
990
+ const singedTransaction = serializeSignedTransaction(
991
+ jsonTransaction,
992
+ signature
993
+ );
994
+ const signedTxBase64 = toBase64(singedTransaction);
995
+ updateTxHistory({
996
+ status: "Pending",
997
+ txId,
998
+ tx: jsonTransaction,
999
+ signature,
1000
+ signedTxBase64,
1001
+ txHash,
1002
+ finalState: false
1003
+ });
1004
+ sendTxToRpc(signedTxBase64, waitUntil, txId);
1005
+ return txId;
1006
+ },
1007
+ // Authentication Methods
1008
+ async requestSignIn({ contractId }) {
1009
+ const privateKey = privateKeyFromRandom();
1010
+ updateState({
1011
+ accessKeyContractId: contractId,
1012
+ accountId: null,
1013
+ privateKey
1014
+ });
1015
+ const publicKey = publicKeyFromPrivate(privateKey);
1016
+ const result = await _adapter.signIn({
1017
+ networkId: _config.networkId,
1018
+ contractId,
1019
+ publicKey
1020
+ });
1021
+ console.log("Sign in result:", result);
1022
+ if (result.error) {
1023
+ throw new Error(`Wallet error: ${result.error}`);
1024
+ }
1025
+ if (result.url) {
1026
+ console.log("Redirecting to wallet:", result.url);
1027
+ setTimeout(() => {
1028
+ window.location.href = result.url;
1029
+ }, 100);
1030
+ } else if (result.accountId) {
1031
+ updateState({
1032
+ accountId: result.accountId
1033
+ });
1034
+ }
1035
+ },
1036
+ signOut() {
1037
+ updateState({
1038
+ accountId: null,
1039
+ privateKey: null,
1040
+ contractId: null
1041
+ });
1042
+ },
1043
+ // Event Handlers
1044
+ onAccount(callback) {
1045
+ _eventListeners.account.add(callback);
1046
+ if (_unbroadcastedEvents.account.length > 0) {
1047
+ const events = _unbroadcastedEvents.account;
1048
+ _unbroadcastedEvents.account = [];
1049
+ events.forEach(notifyAccountListeners);
1050
+ }
1051
+ },
1052
+ onTx(callback) {
1053
+ _eventListeners.tx.add(callback);
1054
+ if (_unbroadcastedEvents.tx.length > 0) {
1055
+ const events = _unbroadcastedEvents.tx;
1056
+ _unbroadcastedEvents.tx = [];
1057
+ events.forEach(notifyTxListeners);
1058
+ }
1059
+ },
1060
+ // Action Helpers
1061
+ actions: {
1062
+ functionCall: ({ methodName, gas, deposit, args, argsBase64 }) => ({
1063
+ type: "FunctionCall",
1064
+ methodName,
1065
+ args,
1066
+ argsBase64,
1067
+ gas,
1068
+ deposit
1069
+ }),
1070
+ transfer: (yoctoAmount) => ({
1071
+ type: "Transfer",
1072
+ deposit: yoctoAmount
1073
+ }),
1074
+ stakeNEAR: ({ amount, publicKey }) => ({
1075
+ type: "Stake",
1076
+ stake: amount,
1077
+ publicKey
1078
+ }),
1079
+ addFullAccessKey: ({ publicKey }) => ({
1080
+ type: "AddKey",
1081
+ publicKey,
1082
+ accessKey: { permission: "FullAccess" }
1083
+ }),
1084
+ addLimitedAccessKey: ({
1085
+ publicKey,
1086
+ allowance,
1087
+ accountId,
1088
+ methodNames
1089
+ }) => ({
1090
+ type: "AddKey",
1091
+ publicKey,
1092
+ accessKey: {
1093
+ permission: "FunctionCall",
1094
+ allowance,
1095
+ receiverId: accountId,
1096
+ methodNames
1097
+ }
1098
+ }),
1099
+ deleteKey: ({ publicKey }) => ({
1100
+ type: "DeleteKey",
1101
+ publicKey
1102
+ }),
1103
+ deleteAccount: ({ beneficiaryId }) => ({
1104
+ type: "DeleteAccount",
1105
+ beneficiaryId
1106
+ }),
1107
+ createAccount: () => ({
1108
+ type: "CreateAccount"
1109
+ }),
1110
+ deployContract: ({ codeBase64 }) => ({
1111
+ type: "DeployContract",
1112
+ codeBase64
1113
+ })
1114
+ },
1115
+ utils: {
1116
+ toBase64,
1117
+ fromBase64,
1118
+ toBase58: import_base58_js.binary_to_base58,
1119
+ fromBase58: import_base58_js.base58_to_binary
1120
+ }
1121
+ };
1122
+ try {
1123
+ const url = new URL(window.location.href);
1124
+ const accountId = url.searchParams.get("account_id");
1125
+ const publicKey = url.searchParams.get("public_key");
1126
+ const errorCode = url.searchParams.get("errorCode");
1127
+ const errorMessage = url.searchParams.get("errorMessage");
1128
+ const transactionHashes = url.searchParams.get("transactionHashes");
1129
+ const txIds = url.searchParams.get("txIds");
1130
+ if (errorCode || errorMessage) {
1131
+ console.warn(new Error(`Wallet error: ${errorCode} ${errorMessage}`));
1132
+ }
1133
+ if (accountId && publicKey) {
1134
+ if (publicKey === _state.publicKey) {
1135
+ updateState({
1136
+ accountId
1137
+ });
1138
+ } else {
1139
+ console.error(
1140
+ new Error("Public key mismatch from wallet redirect"),
1141
+ publicKey,
1142
+ _state.publicKey
1143
+ );
1144
+ }
1145
+ }
1146
+ if (transactionHashes || txIds) {
1147
+ const txHashes = transactionHashes ? transactionHashes.split(",") : [];
1148
+ const txIdsArray = txIds ? txIds.split(",") : [];
1149
+ if (txIdsArray.length > txHashes.length) {
1150
+ txIdsArray.forEach((txId, i) => {
1151
+ updateTxHistory({
1152
+ txId,
1153
+ status: "RejectedByUser",
1154
+ finalState: true
1155
+ });
1156
+ });
1157
+ } else if (txIdsArray.length === txHashes.length) {
1158
+ txIdsArray.forEach((txId, i) => {
1159
+ updateTxHistory({
1160
+ txId,
1161
+ status: "PendingGotTxHash",
1162
+ txHash: txHashes[i],
1163
+ finalState: false
1164
+ });
1165
+ afterTxSent(txId);
1166
+ });
1167
+ } else {
1168
+ console.error(
1169
+ new Error("Transaction hash mismatch from wallet redirect"),
1170
+ txIdsArray,
1171
+ txHashes
1172
+ );
1173
+ }
1174
+ }
1175
+ url.searchParams.delete("account_id");
1176
+ url.searchParams.delete("public_key");
1177
+ url.searchParams.delete("errorCode");
1178
+ url.searchParams.delete("errorMessage");
1179
+ url.searchParams.delete("all_keys");
1180
+ url.searchParams.delete("transactionHashes");
1181
+ url.searchParams.delete("txIds");
1182
+ window.history.replaceState({}, "", url.toString());
1183
+ } catch (e) {
1184
+ console.error("Error handling wallet redirect:", e);
1185
+ }
1186
+ // Annotate the CommonJS export names for ESM import in node:
1187
+ 0 && (module.exports = {
1188
+ $$,
1189
+ near
1190
+ });
1191
+ //# sourceMappingURL=index.esm.js.map