@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,814 @@
1
+ /* ⋈ 🏃🏻💨 FastNEAR API - https://github.com/fastnear */
2
+ import {
3
+ serializeSignedTransaction,
4
+ serializeTransaction
5
+ } from "./chunk-YKPILPMX.js";
6
+ import {
7
+ privateKeyFromRandom,
8
+ publicKeyFromPrivate,
9
+ sha256,
10
+ signHash
11
+ } from "./chunk-S5Q2EM2B.js";
12
+ import {
13
+ canSignWithLAK,
14
+ fromBase58,
15
+ fromBase64,
16
+ lsGet,
17
+ lsSet,
18
+ toBase58,
19
+ toBase64,
20
+ tryParseJson
21
+ } from "./chunk-2SCAGR3F.js";
22
+
23
+ // src/near.ts
24
+ import Big from "big.js";
25
+
26
+ // ../wallet-adapter/src/index.ts
27
+ var WalletAdapter = class _WalletAdapter {
28
+ /** @type {HTMLIFrameElement} */
29
+ #iframe = null;
30
+ /** @type {string} */
31
+ #targetOrigin;
32
+ /** @type {string} */
33
+ #widgetUrl;
34
+ /** @type {Map<string, Function>} */
35
+ #pending = /* @__PURE__ */ new Map();
36
+ /** @type {WalletState} */
37
+ #state;
38
+ /** @type {Function} */
39
+ #onStateUpdate;
40
+ /** @type {string} */
41
+ #callbackUrl;
42
+ /** @type {string} */
43
+ static defaultWidgetUrl = "https://wallet-adapter.fastnear.com";
44
+ /**
45
+ * @param {WalletAdapterConfig} [config]
46
+ */
47
+ constructor({
48
+ widgetUrl = _WalletAdapter.defaultWidgetUrl,
49
+ targetOrigin = "*",
50
+ onStateUpdate,
51
+ lastState,
52
+ callbackUrl = window.location.href
53
+ } = {}) {
54
+ this.#targetOrigin = targetOrigin;
55
+ this.#widgetUrl = widgetUrl;
56
+ this.#onStateUpdate = onStateUpdate;
57
+ this.#callbackUrl = callbackUrl;
58
+ this.#state = lastState || {};
59
+ window.addEventListener("message", this.#handleMessage.bind(this));
60
+ }
61
+ /**
62
+ * Creates an iframe for wallet interaction
63
+ * @param {string} path - Path to load in iframe
64
+ * @returns {HTMLIFrameElement}
65
+ */
66
+ #createIframe(path) {
67
+ if (this.#iframe) {
68
+ this.#iframe.remove();
69
+ }
70
+ const url = new URL(path, this.#widgetUrl);
71
+ const iframe = document.createElement("iframe");
72
+ iframe.src = url.toString();
73
+ iframe.allow = "usb";
74
+ iframe.style.border = "none";
75
+ iframe.style.zIndex = "10000";
76
+ iframe.style.position = "fixed";
77
+ iframe.style.display = "block";
78
+ iframe.style.top = "0";
79
+ iframe.style.left = "0";
80
+ iframe.style.width = "100%";
81
+ iframe.style.height = "100%";
82
+ document.body.appendChild(iframe);
83
+ this.#iframe = iframe;
84
+ return iframe;
85
+ }
86
+ /**
87
+ * Handles messages from the wallet widget
88
+ * @param {MessageEvent} event
89
+ */
90
+ #handleMessage(event) {
91
+ if (this.#targetOrigin !== "*" && event.origin !== this.#targetOrigin) {
92
+ return;
93
+ }
94
+ const { id, type, action, payload } = event.data;
95
+ if (type !== "wallet-adapter") return;
96
+ if (action === "close") {
97
+ this.#iframe?.remove();
98
+ this.#iframe = null;
99
+ return;
100
+ }
101
+ if (payload?.state) {
102
+ this.#state = { ...this.#state, ...payload.state };
103
+ this.#onStateUpdate?.(this.#state);
104
+ }
105
+ const resolve = this.#pending.get(id);
106
+ if (resolve) {
107
+ this.#pending.delete(id);
108
+ this.#iframe?.remove();
109
+ this.#iframe = null;
110
+ resolve(payload);
111
+ }
112
+ }
113
+ /**
114
+ * Sends a message to the wallet widget
115
+ * @param {string} path - Path to load in iframe
116
+ * @param {string} method - Method to call
117
+ * @param {Object} params - Parameters to pass
118
+ * @returns {Promise<any>}
119
+ */
120
+ async #sendMessage(path, method, params) {
121
+ return new Promise((resolve) => {
122
+ const id = Math.random().toString(36).slice(2);
123
+ this.#pending.set(id, resolve);
124
+ const iframe = this.#createIframe(path);
125
+ iframe.onload = () => {
126
+ iframe.contentWindow?.postMessage(
127
+ {
128
+ type: "wallet-adapter",
129
+ method,
130
+ params: {
131
+ id,
132
+ ...params,
133
+ state: this.#state,
134
+ callbackUrl: params.callbackUrl || this.#callbackUrl
135
+ }
136
+ },
137
+ this.#targetOrigin
138
+ );
139
+ };
140
+ });
141
+ }
142
+ /**
143
+ * Get current wallet state
144
+ * @returns {WalletState}
145
+ */
146
+ getState() {
147
+ return { ...this.#state };
148
+ }
149
+ /**
150
+ * Set current wallet state
151
+ * @param state
152
+ */
153
+ setState(state) {
154
+ this.#state = state;
155
+ }
156
+ /**
157
+ * Sign in with a NEAR wallet
158
+ * @param {SignInConfig} config
159
+ * @returns {Promise<SignInResult>}
160
+ */
161
+ async signIn(config) {
162
+ return this.#sendMessage("/login.html", "signIn", config);
163
+ }
164
+ /**
165
+ * Send a transaction using connected wallet
166
+ * @param {TransactionConfig} config
167
+ * @returns {Promise<TransactionResult>}
168
+ */
169
+ async sendTransactions(config) {
170
+ return this.#sendMessage("/send.html", "sendTransactions", config);
171
+ }
172
+ /**
173
+ * Clean up adapter resources
174
+ */
175
+ destroy() {
176
+ window.removeEventListener("message", this.#handleMessage);
177
+ this.#iframe?.remove();
178
+ this.#iframe = null;
179
+ }
180
+ };
181
+
182
+ // src/near.ts
183
+ Big.DP = 27;
184
+ var MaxBlockDelayMs = 1e3 * 60 * 60 * 6;
185
+ var WIDGET_URL = "http://localhost:3000/";
186
+ var DEFAULT_NETWORK_ID = "mainnet";
187
+ var NETWORKS = {
188
+ testnet: {
189
+ networkId: "testnet",
190
+ nodeUrl: "https://rpc.testnet.fastnear.com/"
191
+ },
192
+ mainnet: {
193
+ networkId: "mainnet",
194
+ nodeUrl: "https://rpc.mainnet.fastnear.com/"
195
+ }
196
+ };
197
+ var _config = lsGet("config") || { ...NETWORKS[DEFAULT_NETWORK_ID] };
198
+ var _state = lsGet("state") || {};
199
+ try {
200
+ _state.publicKey = _state.privateKey ? publicKeyFromPrivate(_state.privateKey) : null;
201
+ } catch (e) {
202
+ console.error("Error parsing private key:", e);
203
+ _state.privateKey = null;
204
+ lsSet("nonce", null);
205
+ }
206
+ var _txHistory = lsGet("txHistory") || {};
207
+ var _eventListeners = {
208
+ account: /* @__PURE__ */ new Set(),
209
+ tx: /* @__PURE__ */ new Set()
210
+ };
211
+ var _unbroadcastedEvents = {
212
+ account: [],
213
+ tx: []
214
+ };
215
+ function getWalletAdapterState() {
216
+ return {
217
+ publicKey: _state.publicKey,
218
+ accountId: _state.accountId,
219
+ lastWalletId: _state.lastWalletId,
220
+ networkId: DEFAULT_NETWORK_ID
221
+ };
222
+ }
223
+ var _adapter;
224
+ function updateState(newState) {
225
+ const oldState = _state;
226
+ _state = { ..._state, ...newState };
227
+ lsSet("state", {
228
+ accountId: _state.accountId,
229
+ privateKey: _state.privateKey,
230
+ lastWalletId: _state.lastWalletId,
231
+ accessKeyContractId: _state.accessKeyContractId
232
+ });
233
+ if (newState.hasOwnProperty("privateKey") && newState.privateKey !== oldState.privateKey) {
234
+ _state.publicKey = newState.privateKey ? publicKeyFromPrivate(newState.privateKey) : null;
235
+ lsSet("nonce", null);
236
+ }
237
+ if (newState.accountId !== oldState.accountId) {
238
+ notifyAccountListeners(newState.accountId);
239
+ }
240
+ if (newState.hasOwnProperty("lastWalletId") && newState.lastWalletId !== oldState.lastWalletId || newState.hasOwnProperty("accountId") && newState.accountId !== oldState.accountId || newState.hasOwnProperty("privateKey") && newState.privateKey !== oldState.privateKey) {
241
+ _adapter.setState(getWalletAdapterState());
242
+ }
243
+ }
244
+ function updateTxHistory(txStatus) {
245
+ const txId = txStatus.txId;
246
+ _txHistory[txId] = {
247
+ ..._txHistory[txId] ?? {},
248
+ ...txStatus,
249
+ updateTimestamp: Date.now()
250
+ };
251
+ lsSet("txHistory", _txHistory);
252
+ notifyTxListeners(_txHistory[txId]);
253
+ }
254
+ function onAdapterStateUpdate(state) {
255
+ console.log("Adapter state update:", state);
256
+ const { accountId, lastWalletId, privateKey } = state;
257
+ updateState({
258
+ accountId,
259
+ lastWalletId,
260
+ ...privateKey && { privateKey }
261
+ });
262
+ }
263
+ _adapter = new WalletAdapter({
264
+ onStateUpdate: onAdapterStateUpdate,
265
+ lastState: getWalletAdapterState(),
266
+ widgetUrl: WIDGET_URL
267
+ });
268
+ function parseJsonFromBytes(bytes) {
269
+ try {
270
+ const decoder = new TextDecoder();
271
+ return JSON.parse(decoder.decode(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)));
272
+ } catch (e) {
273
+ try {
274
+ return bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
275
+ } catch (e2) {
276
+ return bytes;
277
+ }
278
+ }
279
+ }
280
+ function withBlockId(params, blockId) {
281
+ return blockId === "final" || blockId === "optimistic" ? { ...params, finality: blockId } : !!blockId ? { ...params, block_id: blockId } : { ...params, finality: "optimistic" };
282
+ }
283
+ async function queryRpc(method, params) {
284
+ const response = await fetch(_config.nodeUrl, {
285
+ method: "POST",
286
+ headers: { "Content-Type": "application/json" },
287
+ body: JSON.stringify({
288
+ jsonrpc: "2.0",
289
+ id: `fastnear-${Date.now()}`,
290
+ method,
291
+ params
292
+ })
293
+ });
294
+ const result = await response.json();
295
+ if (result.error) {
296
+ throw new Error(JSON.stringify(result.error));
297
+ }
298
+ return result.result;
299
+ }
300
+ function afterTxSent(txId) {
301
+ queryRpc("tx", {
302
+ tx_hash: _txHistory[txId].txHash,
303
+ sender_account_id: _txHistory[txId].tx.signerId,
304
+ wait_until: "EXECUTED_OPTIMISTIC"
305
+ }).then((result) => {
306
+ const successValue = result?.status?.SuccessValue;
307
+ updateTxHistory({
308
+ txId,
309
+ status: "Executed",
310
+ result,
311
+ successValue: successValue ? tryParseJson(fromBase64(successValue)) : void 0,
312
+ finalState: true
313
+ });
314
+ }).catch((error) => {
315
+ updateTxHistory({
316
+ txId,
317
+ status: "ErrorAfterIncluded",
318
+ error: tryParseJson(error.message),
319
+ finalState: true
320
+ });
321
+ });
322
+ }
323
+ function sendTxToRpc(signedTxBase64, waitUntil, txId) {
324
+ queryRpc("send_tx", {
325
+ signed_tx_base64: signedTxBase64,
326
+ wait_until: waitUntil ?? "INCLUDED"
327
+ }).then((result) => {
328
+ console.log("Transaction included:", result);
329
+ updateTxHistory({
330
+ txId,
331
+ status: "Included",
332
+ finalState: false
333
+ });
334
+ afterTxSent(txId);
335
+ }).catch((error) => {
336
+ updateTxHistory({
337
+ txId,
338
+ status: "Error",
339
+ error: tryParseJson(error.message),
340
+ finalState: false
341
+ });
342
+ });
343
+ }
344
+ function notifyAccountListeners(accountId) {
345
+ if (_eventListeners.account.size === 0) {
346
+ _unbroadcastedEvents.account.push(accountId);
347
+ return;
348
+ }
349
+ _eventListeners.account.forEach((callback) => {
350
+ try {
351
+ callback(accountId);
352
+ } catch (e) {
353
+ console.error(e);
354
+ }
355
+ });
356
+ }
357
+ function notifyTxListeners(tx) {
358
+ if (_eventListeners.tx.size === 0) {
359
+ _unbroadcastedEvents.tx.push(tx);
360
+ return;
361
+ }
362
+ _eventListeners.tx.forEach((callback) => {
363
+ try {
364
+ callback(tx);
365
+ } catch (e) {
366
+ console.error(e);
367
+ }
368
+ });
369
+ }
370
+ function convertUnit(s, ...args) {
371
+ if (Array.isArray(s)) {
372
+ s = s.reduce((acc, part, i) => {
373
+ return acc + (args[i - 1] ?? "") + part;
374
+ });
375
+ }
376
+ if (typeof s == "string") {
377
+ let match = s.match(/([0-9.,_]+)\s*([a-zA-Z]+)?/);
378
+ if (match) {
379
+ let amount = match[1].replace(/[_,]/g, "");
380
+ let unitPart = match[2];
381
+ if (unitPart) {
382
+ switch (unitPart.toLowerCase()) {
383
+ case "near":
384
+ return Big(amount).mul(Big(10).pow(24)).toFixed(0);
385
+ case "tgas":
386
+ return Big(amount).mul(Big(10).pow(12)).toFixed(0);
387
+ case "ggas":
388
+ return Big(amount).mul(Big(10).pow(9)).toFixed(0);
389
+ case "gas":
390
+ return Big(amount).toFixed(0);
391
+ default:
392
+ throw new Error(`Unknown unit: ${unit}`);
393
+ }
394
+ } else {
395
+ return Big(amount).toFixed(0);
396
+ }
397
+ }
398
+ }
399
+ return Big(s).toFixed(0);
400
+ }
401
+ var api = {
402
+ // Context
403
+ get accountId() {
404
+ return _state.accountId;
405
+ },
406
+ get publicKey() {
407
+ return _state.publicKey;
408
+ },
409
+ config(newConfig) {
410
+ if (newConfig) {
411
+ if (newConfig.networkId && _config.networkId !== newConfig.networkId) {
412
+ _config = { ...NETWORKS[newConfig.networkId] };
413
+ updateState({
414
+ accountId: null,
415
+ privateKey: null,
416
+ lastWalletId: null
417
+ });
418
+ lsSet("block", null);
419
+ _txHistory = {};
420
+ lsSet("txHistory", _txHistory);
421
+ }
422
+ _config = { ..._config, ...newConfig };
423
+ lsSet("config", _config);
424
+ }
425
+ return _config;
426
+ },
427
+ get authStatus() {
428
+ if (!_state.accountId) {
429
+ return "SignedOut";
430
+ }
431
+ const accessKey = _state.publicKey;
432
+ const contractId = _state.accessKeyContractId;
433
+ if (accessKey && contractId && _state.privateKey) {
434
+ return {
435
+ type: "SignedInWithLimitedAccessKey",
436
+ accessKey,
437
+ contractId
438
+ };
439
+ }
440
+ return "SignedIn";
441
+ },
442
+ // Query Methods
443
+ async view({ contractId, methodName, args, argsBase64, blockId }) {
444
+ const encodedArgs = argsBase64 || (args ? toBase64(JSON.stringify(args)) : "");
445
+ const result = await queryRpc(
446
+ "query",
447
+ withBlockId(
448
+ {
449
+ request_type: "call_function",
450
+ account_id: contractId,
451
+ method_name: methodName,
452
+ args_base64: encodedArgs
453
+ },
454
+ blockId
455
+ )
456
+ );
457
+ return parseJsonFromBytes(result.result);
458
+ },
459
+ async account({ accountId, blockId }) {
460
+ return queryRpc(
461
+ "query",
462
+ withBlockId(
463
+ {
464
+ request_type: "view_account",
465
+ account_id: accountId
466
+ },
467
+ blockId
468
+ )
469
+ );
470
+ },
471
+ async block({ blockId }) {
472
+ return queryRpc("block", withBlockId({}, blockId));
473
+ },
474
+ async accessKey({ accountId, publicKey, blockId }) {
475
+ return queryRpc(
476
+ "query",
477
+ withBlockId(
478
+ {
479
+ request_type: "view_access_key",
480
+ account_id: accountId,
481
+ public_key: publicKey
482
+ },
483
+ blockId
484
+ )
485
+ );
486
+ },
487
+ async tx({ txHash, accountId }) {
488
+ return queryRpc("tx", [txHash, accountId]);
489
+ },
490
+ localTxHistory() {
491
+ return [..._txHistory];
492
+ },
493
+ // Transaction Methods
494
+ async sendTx({ receiverId, actions, waitUntil }) {
495
+ const signerId = _state.accountId;
496
+ if (!signerId) {
497
+ throw new Error("Not signed in");
498
+ }
499
+ const publicKey = _state.publicKey;
500
+ const privateKey = _state.privateKey;
501
+ const txId = `tx-${Date.now()}-${Math.random()}`;
502
+ if (!privateKey || receiverId !== _state.accessKeyContractId || !canSignWithLAK(actions)) {
503
+ const jsonTransaction2 = {
504
+ signerId,
505
+ receiverId,
506
+ actions
507
+ };
508
+ updateTxHistory({
509
+ status: "Pending",
510
+ txId,
511
+ tx: jsonTransaction2,
512
+ finalState: false
513
+ });
514
+ const url = new URL(window.location.href);
515
+ url.searchParams.set("txIds", txId);
516
+ _adapter.sendTransactions({
517
+ transactions: [jsonTransaction2],
518
+ callbackUrl: url.toString()
519
+ }).then((result) => {
520
+ console.log("Transaction result:", result);
521
+ if (result.url) {
522
+ console.log("Redirecting to wallet:", result.url);
523
+ setTimeout(() => {
524
+ window.location.href = result.url;
525
+ }, 100);
526
+ } else if (result.outcomes) {
527
+ result.outcomes.forEach((result2) => {
528
+ updateTxHistory({
529
+ txId,
530
+ status: "Executed",
531
+ result: result2,
532
+ txHash: result2.transaction.hash,
533
+ finalState: true
534
+ });
535
+ });
536
+ } else if (result.rejected) {
537
+ updateTxHistory({
538
+ txId,
539
+ status: "RejectedByUser",
540
+ finalState: true
541
+ });
542
+ } else if (result.error) {
543
+ updateTxHistory({
544
+ txId,
545
+ status: "Error",
546
+ error: tryParseJson(result.error),
547
+ finalState: true
548
+ });
549
+ }
550
+ }).catch((error) => {
551
+ updateTxHistory({
552
+ txId,
553
+ status: "Error",
554
+ error: tryParseJson(error.message),
555
+ finalState: true
556
+ });
557
+ });
558
+ return txId;
559
+ }
560
+ const toDoPromises = {};
561
+ let nonce = lsGet("nonce");
562
+ if (nonce === null || nonce === void 0) {
563
+ toDoPromises.nonce = this.accessKey({
564
+ accountId: signerId,
565
+ publicKey
566
+ }).then((accessKey) => {
567
+ if (accessKey.error) {
568
+ throw new Error(`Access key error: ${accessKey.error}`);
569
+ }
570
+ lsSet("nonce", accessKey.nonce);
571
+ return accessKey.nonce;
572
+ });
573
+ }
574
+ let block = lsGet("block");
575
+ if (!block || parseFloat(block.header.timestamp_nanosec) / 1e6 + MaxBlockDelayMs < Date.now()) {
576
+ toDoPromises.block = this.block({ blockId: "final" }).then((block2) => {
577
+ block2 = {
578
+ header: {
579
+ prev_hash: block2.header.prev_hash,
580
+ timestamp_nanosec: block2.header.timestamp_nanosec
581
+ }
582
+ };
583
+ lsSet("block", block2);
584
+ return block2;
585
+ });
586
+ }
587
+ if (Object.keys(toDoPromises).length > 0) {
588
+ let results = await Promise.all(Object.values(toDoPromises));
589
+ for (let i = 0; i < results.length; i++) {
590
+ if (Object.keys(toDoPromises)[i] === "nonce") {
591
+ nonce = results[i];
592
+ } else if (Object.keys(toDoPromises)[i] === "block") {
593
+ block = results[i];
594
+ }
595
+ }
596
+ }
597
+ const newNonce = nonce + 1;
598
+ lsSet("nonce", newNonce);
599
+ const blockHash = block.header.prev_hash;
600
+ const jsonTransaction = {
601
+ signerId,
602
+ publicKey,
603
+ nonce: newNonce,
604
+ receiverId,
605
+ blockHash,
606
+ actions
607
+ };
608
+ console.log("Transaction:", jsonTransaction);
609
+ const transaction = serializeTransaction(jsonTransaction);
610
+ const txHash = toBase58(sha256(transaction));
611
+ const signature = signHash(txHash, privateKey);
612
+ const singedTransaction = serializeSignedTransaction(
613
+ jsonTransaction,
614
+ signature
615
+ );
616
+ const signedTxBase64 = toBase64(singedTransaction);
617
+ updateTxHistory({
618
+ status: "Pending",
619
+ txId,
620
+ tx: jsonTransaction,
621
+ signature,
622
+ signedTxBase64,
623
+ txHash,
624
+ finalState: false
625
+ });
626
+ sendTxToRpc(signedTxBase64, waitUntil, txId);
627
+ return txId;
628
+ },
629
+ // Authentication Methods
630
+ async requestSignIn({ contractId }) {
631
+ const privateKey = privateKeyFromRandom();
632
+ updateState({
633
+ accessKeyContractId: contractId,
634
+ accountId: null,
635
+ privateKey
636
+ });
637
+ const publicKey = publicKeyFromPrivate(privateKey);
638
+ const result = await _adapter.signIn({
639
+ networkId: _config.networkId,
640
+ contractId,
641
+ publicKey
642
+ });
643
+ console.log("Sign in result:", result);
644
+ if (result.error) {
645
+ throw new Error(`Wallet error: ${result.error}`);
646
+ }
647
+ if (result.url) {
648
+ console.log("Redirecting to wallet:", result.url);
649
+ setTimeout(() => {
650
+ window.location.href = result.url;
651
+ }, 100);
652
+ } else if (result.accountId) {
653
+ updateState({
654
+ accountId: result.accountId
655
+ });
656
+ }
657
+ },
658
+ signOut() {
659
+ updateState({
660
+ accountId: null,
661
+ privateKey: null,
662
+ contractId: null
663
+ });
664
+ },
665
+ // Event Handlers
666
+ onAccount(callback) {
667
+ _eventListeners.account.add(callback);
668
+ if (_unbroadcastedEvents.account.length > 0) {
669
+ const events = _unbroadcastedEvents.account;
670
+ _unbroadcastedEvents.account = [];
671
+ events.forEach(notifyAccountListeners);
672
+ }
673
+ },
674
+ onTx(callback) {
675
+ _eventListeners.tx.add(callback);
676
+ if (_unbroadcastedEvents.tx.length > 0) {
677
+ const events = _unbroadcastedEvents.tx;
678
+ _unbroadcastedEvents.tx = [];
679
+ events.forEach(notifyTxListeners);
680
+ }
681
+ },
682
+ // Action Helpers
683
+ actions: {
684
+ functionCall: ({ methodName, gas, deposit, args, argsBase64 }) => ({
685
+ type: "FunctionCall",
686
+ methodName,
687
+ args,
688
+ argsBase64,
689
+ gas,
690
+ deposit
691
+ }),
692
+ transfer: (yoctoAmount) => ({
693
+ type: "Transfer",
694
+ deposit: yoctoAmount
695
+ }),
696
+ stakeNEAR: ({ amount, publicKey }) => ({
697
+ type: "Stake",
698
+ stake: amount,
699
+ publicKey
700
+ }),
701
+ addFullAccessKey: ({ publicKey }) => ({
702
+ type: "AddKey",
703
+ publicKey,
704
+ accessKey: { permission: "FullAccess" }
705
+ }),
706
+ addLimitedAccessKey: ({
707
+ publicKey,
708
+ allowance,
709
+ accountId,
710
+ methodNames
711
+ }) => ({
712
+ type: "AddKey",
713
+ publicKey,
714
+ accessKey: {
715
+ permission: "FunctionCall",
716
+ allowance,
717
+ receiverId: accountId,
718
+ methodNames
719
+ }
720
+ }),
721
+ deleteKey: ({ publicKey }) => ({
722
+ type: "DeleteKey",
723
+ publicKey
724
+ }),
725
+ deleteAccount: ({ beneficiaryId }) => ({
726
+ type: "DeleteAccount",
727
+ beneficiaryId
728
+ }),
729
+ createAccount: () => ({
730
+ type: "CreateAccount"
731
+ }),
732
+ deployContract: ({ codeBase64 }) => ({
733
+ type: "DeployContract",
734
+ codeBase64
735
+ })
736
+ },
737
+ utils: {
738
+ toBase64,
739
+ fromBase64,
740
+ toBase58,
741
+ fromBase58
742
+ }
743
+ };
744
+ try {
745
+ const url = new URL(window.location.href);
746
+ const accountId = url.searchParams.get("account_id");
747
+ const publicKey = url.searchParams.get("public_key");
748
+ const errorCode = url.searchParams.get("errorCode");
749
+ const errorMessage = url.searchParams.get("errorMessage");
750
+ const transactionHashes = url.searchParams.get("transactionHashes");
751
+ const txIds = url.searchParams.get("txIds");
752
+ if (errorCode || errorMessage) {
753
+ console.warn(new Error(`Wallet error: ${errorCode} ${errorMessage}`));
754
+ }
755
+ if (accountId && publicKey) {
756
+ if (publicKey === _state.publicKey) {
757
+ updateState({
758
+ accountId
759
+ });
760
+ } else {
761
+ console.error(
762
+ new Error("Public key mismatch from wallet redirect"),
763
+ publicKey,
764
+ _state.publicKey
765
+ );
766
+ }
767
+ }
768
+ if (transactionHashes || txIds) {
769
+ const txHashes = transactionHashes ? transactionHashes.split(",") : [];
770
+ const txIdsArray = txIds ? txIds.split(",") : [];
771
+ if (txIdsArray.length > txHashes.length) {
772
+ txIdsArray.forEach((txId, i) => {
773
+ updateTxHistory({
774
+ txId,
775
+ status: "RejectedByUser",
776
+ finalState: true
777
+ });
778
+ });
779
+ } else if (txIdsArray.length === txHashes.length) {
780
+ txIdsArray.forEach((txId, i) => {
781
+ updateTxHistory({
782
+ txId,
783
+ status: "PendingGotTxHash",
784
+ txHash: txHashes[i],
785
+ finalState: false
786
+ });
787
+ afterTxSent(txId);
788
+ });
789
+ } else {
790
+ console.error(
791
+ new Error("Transaction hash mismatch from wallet redirect"),
792
+ txIdsArray,
793
+ txHashes
794
+ );
795
+ }
796
+ }
797
+ url.searchParams.delete("account_id");
798
+ url.searchParams.delete("public_key");
799
+ url.searchParams.delete("errorCode");
800
+ url.searchParams.delete("errorMessage");
801
+ url.searchParams.delete("all_keys");
802
+ url.searchParams.delete("transactionHashes");
803
+ url.searchParams.delete("txIds");
804
+ window.history.replaceState({}, "", url.toString());
805
+ } catch (e) {
806
+ console.error("Error handling wallet redirect:", e);
807
+ }
808
+
809
+ export {
810
+ parseJsonFromBytes,
811
+ convertUnit,
812
+ api
813
+ };
814
+ //# sourceMappingURL=chunk-B2HMQPYI.js.map