@gardenfi/wallet-connectors 3.0.0-beta.2 → 3.0.0-beta.4

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 (48) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.js +12 -7
  3. package/dist/index10.cjs +1 -1
  4. package/dist/index10.js +83 -3
  5. package/dist/index11.cjs +1 -1
  6. package/dist/index11.js +108 -2
  7. package/dist/index12.cjs +1 -1
  8. package/dist/index12.js +81 -2
  9. package/dist/index13.cjs +1 -0
  10. package/dist/index13.js +68 -0
  11. package/dist/index14.cjs +3 -0
  12. package/dist/index14.js +116 -0
  13. package/dist/index15.cjs +1 -0
  14. package/dist/index15.js +4 -0
  15. package/dist/index16.cjs +1 -0
  16. package/dist/index16.js +5 -0
  17. package/dist/index17.cjs +1 -0
  18. package/dist/index17.js +4 -0
  19. package/dist/index18.cjs +1 -0
  20. package/dist/index18.js +4 -0
  21. package/dist/index2.cjs +1 -1
  22. package/dist/index2.js +75 -97
  23. package/dist/index5.cjs +1 -1
  24. package/dist/index5.js +89 -61
  25. package/dist/index6.cjs +1 -1
  26. package/dist/index6.js +24 -82
  27. package/dist/index7.cjs +1 -1
  28. package/dist/index7.js +140 -79
  29. package/dist/index8.cjs +1 -1
  30. package/dist/index8.js +195 -70
  31. package/dist/index9.cjs +1 -1
  32. package/dist/index9.js +41 -45
  33. package/dist/src/bitcoin/bitcoin.types.d.ts +1 -1
  34. package/dist/src/bitcoin/btcWalletsProvider.d.ts +1 -1
  35. package/dist/src/bitcoin/btcWalletsProvider.types.d.ts +0 -7
  36. package/dist/src/bitcoin/index.d.ts +3 -3
  37. package/dist/src/index.d.ts +1 -0
  38. package/dist/src/litecoin/constants.d.ts +24 -0
  39. package/dist/src/litecoin/index.d.ts +5 -0
  40. package/dist/src/litecoin/litecoin.types.d.ts +51 -0
  41. package/dist/src/litecoin/ltcWalletsProvider.d.ts +17 -0
  42. package/dist/src/litecoin/ltcWalletsProvider.types.d.ts +22 -0
  43. package/dist/src/litecoin/providers/enkrypt/enkrypt.types.d.ts +22 -0
  44. package/dist/src/litecoin/providers/enkrypt/provider.d.ts +25 -0
  45. package/dist/src/litecoin/providers/litescribe/litescribe.types.d.ts +18 -0
  46. package/dist/src/litecoin/providers/litescribe/provider.d.ts +26 -0
  47. package/dist/src/litecoin/utils.d.ts +12 -0
  48. package/package.json +6 -5
package/dist/index9.js CHANGED
@@ -1,68 +1,64 @@
1
- var u = (r) => {
2
- throw TypeError(r);
1
+ var y = (e) => {
2
+ throw TypeError(e);
3
3
  };
4
- var h = (r, t, e) => t.has(r) || u("Cannot " + e);
5
- var s = (r, t, e) => (h(r, t, "read from private field"), e ? e.call(r) : t.get(r)), w = (r, t, e) => t.has(r) ? u("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(r) : t.set(r, e), p = (r, t, e, l) => (h(r, t, "write to private field"), l ? l.call(r, e) : t.set(r, e), e);
6
- import { KeplrBitcoinChainType as d } from "./index12.js";
7
- import { WALLET_CONFIG as a } from "./index3.js";
8
- import { Network as o, Err as c, Ok as E, executeWithTryCatch as i } from "@gardenfi/utils";
9
- var n;
10
- class K {
11
- constructor(t) {
12
- w(this, n);
13
- this.address = "", this.id = a.Keplr.id, this.name = a.Keplr.name, this.icon = a.Keplr.icon, p(this, n, t);
4
+ var g = (e, t, r) => t.has(e) || y("Cannot " + r);
5
+ var n = (e, t, r) => (g(e, t, "read from private field"), r ? r.call(e) : t.get(e)), d = (e, t, r) => t.has(e) ? y("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(e) : t.set(e, r), a = (e, t, r, w) => (g(e, t, "write to private field"), w ? w.call(e, r) : t.set(e, r), r);
6
+ import { Ok as c, Err as o, executeWithTryCatch as h, Network as l } from "@gardenfi/utils";
7
+ import { WALLET_CONFIG as u } from "./index3.js";
8
+ var i, s;
9
+ class E {
10
+ constructor(t, r) {
11
+ d(this, i);
12
+ d(this, s);
13
+ this.address = "", this.id = u.OKX.id, this.name = u.OKX.name, this.icon = u.OKX.icon, this.disconnect = () => (this.address = "", n(this, i).disconnect(), Promise.resolve(c("Disconnected OKX wallet"))), a(this, i, t), a(this, s, r);
14
14
  }
15
- async connect(t) {
16
- if (t || (t = o.MAINNET), t === o.TESTNET)
17
- return c("Keplr wallet does not support testnet4");
15
+ async connect() {
18
16
  try {
19
- const e = await s(this, n).requestAccounts();
20
- return e.length > 0 && (this.address = e[0]), E({
17
+ const t = await n(this, i).connect();
18
+ return !t || !t.address ? o("Failed to connect to OKX wallet") : (this.address = t.address, c({
21
19
  address: this.address,
22
20
  provider: this,
23
- network: t,
24
- id: a.Keplr.id
25
- });
26
- } catch (e) {
27
- return c("Error while connecting to the Keplr wallet", e);
21
+ network: n(this, s),
22
+ id: u.OKX.id
23
+ }));
24
+ } catch (t) {
25
+ return o("Error while connecting to the OKX wallet", t);
28
26
  }
29
27
  }
28
+ async getPublicKey() {
29
+ return await h(async () => await n(this, i).getPublicKey(), "Error while getting public key from OKX wallet");
30
+ }
30
31
  async requestAccounts() {
31
- return await i(async () => await s(this, n).requestAccounts(), "Error while requesting accounts from the Keplr wallet");
32
+ const t = await this.connect();
33
+ return t.ok ? c([t.val.address]) : o(t.error);
32
34
  }
33
35
  async getAccounts() {
34
- return await i(async () => await s(this, n).getAccounts(), "Error while getting accounts from the Keplr wallet");
36
+ return n(this, s) === l.TESTNET ? await this.requestAccounts() : await h(async () => await n(this, i).getAccounts(), "Error while getting accounts from OKX wallet");
35
37
  }
36
38
  async getNetwork() {
37
- return await i(async () => {
38
- const t = await s(this, n).getChain();
39
- if (t.enum === d.MAINNET)
40
- return o.MAINNET;
41
- if (t.enum === d.TESTNET)
42
- return o.TESTNET;
43
- throw new Error("Invalid or unsupported network" + t.enum);
44
- }, "Error while getting network from the Keplr wallet");
39
+ return c(n(this, s));
45
40
  }
46
41
  async switchNetwork() {
47
- return c("Keplr wallet does not support testnet4");
42
+ a(this, s, n(this, s) === l.MAINNET ? l.TESTNET : l.MAINNET);
43
+ const t = await this.connect();
44
+ return t.error ? o(
45
+ `Failed to connect to ${n(this, s)}: ${t.error}`
46
+ ) : c(n(this, s));
48
47
  }
49
48
  async getBalance() {
50
- return await i(async () => await s(this, n).getBalance(), "Error while getting balance from Keplr wallet");
51
- }
52
- async sendBitcoin(t, e) {
53
- return await i(async () => await s(this, n).sendBitcoin(t, e), "Error while sending bitcoin from Keplr wallet");
49
+ return await h(async () => await n(this, i).getBalance(), "Error while getting balance from OKX wallet");
54
50
  }
55
- on(t, e) {
56
- s(this, n).on(t, e);
51
+ async sendBitcoin(t, r) {
52
+ return await h(async () => await n(this, i).sendBitcoin(t, r), "Error while sending bitcoin from OKX wallet");
57
53
  }
58
- off(t, e) {
59
- s(this, n).off(t, e);
54
+ on(t, r) {
55
+ n(this, i).on(t, r);
60
56
  }
61
- async disconnect() {
62
- return await s(this, n).disconnect(), this.address = "", E("Disconnected Keplr wallet");
57
+ off(t, r) {
58
+ n(this, i).off(t, r);
63
59
  }
64
60
  }
65
- n = new WeakMap();
61
+ i = new WeakMap(), s = new WeakMap();
66
62
  export {
67
- K as KeplrProvider
63
+ E as OKXProvider
68
64
  };
@@ -12,7 +12,7 @@ export type Connect = {
12
12
  network: Network;
13
13
  id: WalletId;
14
14
  };
15
- export type WalletId = (typeof WALLET_CONFIG)[keyof typeof WALLET_CONFIG]['id'] | string;
15
+ export type WalletId = (typeof WALLET_CONFIG)[keyof typeof WALLET_CONFIG]['id'];
16
16
  export type ProviderEvents = {
17
17
  accountsChanged: (accounts: string[]) => void;
18
18
  };
@@ -28,5 +28,5 @@ declare global {
28
28
  };
29
29
  }
30
30
  }
31
- export declare const BTCWalletProvider: ({ children, network, store, wallets, }: BTCWalletProviderProps) => React.JSX.Element;
31
+ export declare const BTCWalletProvider: ({ children, network, store, }: BTCWalletProviderProps) => React.JSX.Element;
32
32
  export declare const useBitcoinWallet: () => BTCWalletProviderContextType;
@@ -15,15 +15,8 @@ export type BTCWalletProviderContextType = {
15
15
  isConnecting: boolean;
16
16
  isConnected: boolean;
17
17
  };
18
- export type CustomWalletConfig = {
19
- id: string;
20
- provider: IInjectedBitcoinProvider;
21
- registerConnect?: (connect: () => void) => void | (() => void);
22
- registerDisconnect?: (disconnect: () => void) => void | (() => void);
23
- };
24
18
  export type BTCWalletProviderProps = {
25
19
  network: Network;
26
20
  children: React.ReactNode;
27
21
  store: IStore;
28
- wallets?: CustomWalletConfig[];
29
22
  };
@@ -1,5 +1,5 @@
1
1
  export { BTCWalletProvider, useBitcoinWallet } from './btcWalletsProvider';
2
- export { SupportedWallets } from './constants';
2
+ export { SupportedWallets as SupportedBTCWallets } from './constants';
3
3
  export { getBalance } from './utils';
4
- export type { IInjectedBitcoinProvider, Balance, Connect, } from './bitcoin.types';
5
- export type { AvailableWallets, BTCWalletProviderProps, CustomWalletConfig, } from './btcWalletsProvider.types';
4
+ export type { IInjectedBitcoinProvider, Balance } from './bitcoin.types';
5
+ export type { AvailableWallets as AvailableBTCWallets, BTCWalletProviderProps, } from './btcWalletsProvider.types';
@@ -1 +1,2 @@
1
1
  export * from './bitcoin';
2
+ export * from './litecoin';
@@ -0,0 +1,24 @@
1
+ export declare const SupportedWallets: {
2
+ Enkrypt: {
3
+ id: string;
4
+ name: string;
5
+ icon: string;
6
+ };
7
+ LiteScribe: {
8
+ id: string;
9
+ name: string;
10
+ icon: string;
11
+ };
12
+ };
13
+ export declare const WALLET_CONFIG: {
14
+ readonly Enkrypt: {
15
+ readonly id: "enkrypt";
16
+ readonly name: "Enkrypt Wallet";
17
+ readonly icon: "https://2536749467-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWHaZuaEtXZ0lYkuIWo8C%2Fuploads%2FQnJnFL186t5LWCLQofbg%2FEnkrypt%20E%20only%20Color%20logo.svg?alt=media&token=59f66a73-0795-41ea-8166-ec5416a4fc23";
18
+ };
19
+ readonly LiteScribe: {
20
+ readonly id: "litescribe";
21
+ readonly name: "Litescribe Wallet";
22
+ readonly icon: "https://lh3.googleusercontent.com/WRArwMWT7LP-i8OZZI1-LdJXvdT0wEiF-kpXuHu02KxdmyvMfrnZikLefy1SSyW5ozAFYcer5JDOZ-LPnIRKSCVvXJw=s120";
23
+ };
24
+ };
@@ -0,0 +1,5 @@
1
+ export { LTCWalletProvider, useLitecoinWallet } from './ltcWalletsProvider';
2
+ export { SupportedWallets as SupportedLTCWallets } from './constants';
3
+ export { getBalance } from '../bitcoin/utils';
4
+ export type { IInjectedLitecoinProvider, LtcBalance } from './litecoin.types';
5
+ export type { AvailableWallets as AvailableLTCWallets, LTCWalletProviderProps, } from './ltcWalletsProvider.types';
@@ -0,0 +1,51 @@
1
+ import { AsyncResult, Network } from '@gardenfi/utils';
2
+ import { WALLET_CONFIG } from './constants';
3
+
4
+ export type LtcBalance = {
5
+ confirmed: number;
6
+ unconfirmed: number;
7
+ total: number;
8
+ };
9
+ export type Connect = {
10
+ address: string;
11
+ provider: IInjectedLitecoinProvider;
12
+ network: Network;
13
+ id: WalletId;
14
+ };
15
+ export type WalletId = (typeof WALLET_CONFIG)[keyof typeof WALLET_CONFIG]['id'];
16
+ export type ProviderEvents = {
17
+ accountsChanged: (accounts: string[]) => void;
18
+ };
19
+ export interface IInjectedLitecoinProvider {
20
+ id: WalletId;
21
+ address: string;
22
+ name: string;
23
+ icon: string;
24
+ getBalance: () => AsyncResult<LtcBalance, string>;
25
+ /**
26
+ * requests accounts from the wallet, if not connected, it will connect first
27
+ * @returns {AsyncResult<string[], string>}
28
+ */
29
+ requestAccounts: () => AsyncResult<string[], string>;
30
+ /**
31
+ * silently gets accounts if already connected
32
+ * @returns {AsyncResult<string[], string>}
33
+ */
34
+ getAccounts: () => AsyncResult<string[], string>;
35
+ sendLitecoin: (toAddress: string, satoshis: number) => AsyncResult<string, string>;
36
+ getNetwork: () => AsyncResult<Network, string>;
37
+ switchNetwork: () => AsyncResult<Network, string>;
38
+ connect: (network?: Network) => AsyncResult<Connect, string>;
39
+ disconnect: () => AsyncResult<string, string>;
40
+ on<E extends keyof ProviderEvents>(event: E, cb: ProviderEvents[E]): void;
41
+ off<E extends keyof ProviderEvents>(event: E, cb: ProviderEvents[E]): void;
42
+ }
43
+ export type SelectedAccount = {
44
+ address: string;
45
+ publicKey: string;
46
+ };
47
+ export interface LitecoinWallet {
48
+ name: string;
49
+ symbol: string;
50
+ connect: () => AsyncResult<IInjectedLitecoinProvider, string>;
51
+ }
@@ -0,0 +1,17 @@
1
+ import { default as React } from 'react';
2
+ import { LTCWalletProviderContextType, LTCWalletProviderProps } from './ltcWalletsProvider.types';
3
+ import { EnkryptLTCProvider } from './providers/enkrypt/enkrypt.types';
4
+ import { LitescribeLTCProvider } from './providers/litescribe/litescribe.types';
5
+
6
+ declare global {
7
+ interface Window {
8
+ enkrypt?: {
9
+ providers?: {
10
+ bitcoin?: EnkryptLTCProvider;
11
+ };
12
+ };
13
+ litescribe?: LitescribeLTCProvider;
14
+ }
15
+ }
16
+ export declare const LTCWalletProvider: ({ children, network, store, }: LTCWalletProviderProps) => React.JSX.Element;
17
+ export declare const useLitecoinWallet: () => LTCWalletProviderContextType;
@@ -0,0 +1,22 @@
1
+ import { IInjectedLitecoinProvider } from '.';
2
+ import { AsyncResult, IStore, Network, Result } from '@gardenfi/utils';
3
+
4
+ export type AvailableWallets = {
5
+ [key: string]: IInjectedLitecoinProvider;
6
+ };
7
+ export type LTCWalletProviderContextType = {
8
+ availableWallets: AvailableWallets;
9
+ connect: (LitecoinWallet: IInjectedLitecoinProvider, network?: Network) => AsyncResult<void, string>;
10
+ updateAccount: () => Promise<void>;
11
+ provider: IInjectedLitecoinProvider | undefined;
12
+ account: string | undefined;
13
+ network: Network | undefined;
14
+ disconnect: () => Result<void, string>;
15
+ isConnecting: boolean;
16
+ isConnected: boolean;
17
+ };
18
+ export type LTCWalletProviderProps = {
19
+ network: Network;
20
+ children: React.ReactNode;
21
+ store: IStore;
22
+ };
@@ -0,0 +1,22 @@
1
+ export interface EnkryptLTCProvider {
2
+ _selectedAddress: string;
3
+ getAccounts: () => Promise<string[]>;
4
+ requestAccounts: () => Promise<string[]>;
5
+ sendBitcoin: (toAddress: string, satoshis: number) => Promise<string>;
6
+ getBalance: () => Promise<{
7
+ confirmed: number;
8
+ unconfirmed: number;
9
+ total: number;
10
+ }>;
11
+ signPsbt: (psbt: string) => Promise<string>;
12
+ getChain: () => Promise<EnkryptChain>;
13
+ switchChain: () => Promise<EnkryptChain>;
14
+ getPublicKey(): Promise<string>;
15
+ on: (event: string, callback: (data: any) => void) => void;
16
+ off: (event: string, callback: (data: any) => void) => void;
17
+ removeListener: (event: string, callback: (data: any) => void) => void;
18
+ disconnect: () => void;
19
+ }
20
+ export type EnkryptChain = {
21
+ name: string;
22
+ };
@@ -0,0 +1,25 @@
1
+ import { EnkryptLTCProvider } from './enkrypt.types';
2
+ import { AsyncResult, Network } from '@gardenfi/utils';
3
+ import { Connect, IInjectedLitecoinProvider, LtcBalance } from '../../litecoin.types';
4
+
5
+ export declare class EnkryptProvider implements IInjectedLitecoinProvider {
6
+ #private;
7
+ address: string;
8
+ id: "enkrypt";
9
+ name: "Enkrypt Wallet";
10
+ icon: "https://2536749467-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWHaZuaEtXZ0lYkuIWo8C%2Fuploads%2FQnJnFL186t5LWCLQofbg%2FEnkrypt%20E%20only%20Color%20logo.svg?alt=media&token=59f66a73-0795-41ea-8166-ec5416a4fc23";
11
+ constructor(enkryptProvider: EnkryptLTCProvider);
12
+ connect(network?: Network): AsyncResult<Connect, string>;
13
+ requestAccounts(): Promise<import('@gardenfi/utils').Result<string[], string>>;
14
+ getAccounts(): AsyncResult<string[], string>;
15
+ getNetwork(): AsyncResult<Network, string>;
16
+ switchNetwork(): AsyncResult<Network, string>;
17
+ getBalance(): AsyncResult<LtcBalance, string>;
18
+ sendLitecoin(toAddress: string, satoshis: number): AsyncResult<string, string>;
19
+ private buildTransaction;
20
+ private signPsbt;
21
+ private broadcastTransaction;
22
+ on(event: string, callback: (data: any) => void): void;
23
+ off(event: string, callback: (data: any) => void): void;
24
+ disconnect: () => AsyncResult<string, string>;
25
+ }
@@ -0,0 +1,18 @@
1
+ export interface LitescribeLTCProvider {
2
+ requestAccounts(): Promise<string[]>;
3
+ getAccounts(): Promise<string[]>;
4
+ getNetwork(): Promise<LitescribeNetworkEnum>;
5
+ switchNetwork(network: LitescribeNetworkEnum): Promise<void>;
6
+ signPsbt(psbtBase64: string): Promise<string>;
7
+ pushPsbt?(psbtBase64: string): Promise<string>;
8
+ getUtxos?(): Promise<any[]>;
9
+ on(event: string, callback: (data: any) => void): void;
10
+ off(event: string, callback: (data: any) => void): void;
11
+ }
12
+ export type LitescribeChain = {
13
+ name: string;
14
+ };
15
+ export declare enum LitescribeNetworkEnum {
16
+ LIVENET = "livenet",
17
+ TESTNET = "testnet"
18
+ }
@@ -0,0 +1,26 @@
1
+ import { AsyncResult, Network } from '@gardenfi/utils';
2
+ import { LitescribeLTCProvider } from './litescribe.types';
3
+ import { LtcBalance, Connect, IInjectedLitecoinProvider } from '../../litecoin.types';
4
+
5
+ export declare class LitescribeProvider implements IInjectedLitecoinProvider {
6
+ #private;
7
+ address: string;
8
+ id: "litescribe";
9
+ name: "Litescribe Wallet";
10
+ icon: "https://lh3.googleusercontent.com/WRArwMWT7LP-i8OZZI1-LdJXvdT0wEiF-kpXuHu02KxdmyvMfrnZikLefy1SSyW5ozAFYcer5JDOZ-LPnIRKSCVvXJw=s120";
11
+ constructor(litescribeprovider: LitescribeLTCProvider);
12
+ connect(network?: Network): AsyncResult<Connect, string>;
13
+ getBalance(): AsyncResult<LtcBalance, string>;
14
+ requestAccounts(): AsyncResult<string[], string>;
15
+ getAccounts(): AsyncResult<string[], string>;
16
+ sendLitecoin(toAddress: string, satoshis: number): AsyncResult<string, string>;
17
+ private getUTXOs;
18
+ private buildTransaction;
19
+ private signPsbt;
20
+ private broadcastTransaction;
21
+ getNetwork(): AsyncResult<Network, string>;
22
+ switchNetwork(): AsyncResult<Network, string>;
23
+ disconnect(): AsyncResult<string, string>;
24
+ on(event: string, callback: (data: any) => void): void;
25
+ off(event: string, callback: (data: any) => void): void;
26
+ }
@@ -0,0 +1,12 @@
1
+ import { AsyncResult, Network } from '@gardenfi/utils';
2
+ import { LtcBalance } from './litecoin.types';
3
+ import { BitcoinUTXO } from '@gardenfi/core';
4
+
5
+ import * as bitcoin from 'bitcoinjs-lib';
6
+ export declare const LITECOIN_NETWORK: bitcoin.networks.Network;
7
+ export declare const LITECOIN_TESTNET: bitcoin.networks.Network;
8
+ export declare const getLitecoinNetwork: (network: Network) => bitcoin.networks.Network;
9
+ export declare const getBalance: (address: string, network: Network) => AsyncResult<LtcBalance, string>;
10
+ export declare const broadcastTransaction: (signedPsbtBase64: string, network: Network, pushPsbt?: (psbt: string) => Promise<string>) => AsyncResult<string, string>;
11
+ export declare const getUTXOs: (address: string, network: Network) => AsyncResult<BitcoinUTXO[], string>;
12
+ export declare const getRecommendedFeeRate: (network: Network) => AsyncResult<number, string>;
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@gardenfi/wallet-connectors",
3
- "version": "3.0.0-beta.2",
3
+ "version": "3.0.0-beta.4",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "vite build",
7
7
  "test": "vitest run",
8
8
  "dev": "vite build --watch",
9
- "link": "yarn link"
9
+ "link": "bun link"
10
10
  },
11
11
  "files": [
12
12
  "dist"
@@ -37,11 +37,12 @@
37
37
  },
38
38
  "sideEffects": false,
39
39
  "dependencies": {
40
- "@gardenfi/core": "3.0.1-beta.1",
41
- "@gardenfi/utils": "3.0.0-beta.1",
40
+ "@gardenfi/core": "3.0.8-beta.7",
41
+ "@gardenfi/utils": "3.0.0-beta.8",
42
42
  "axios": "^1.7.9",
43
43
  "bitcoinjs-lib": "^6.1.7",
44
+ "bitcore-lib-ltc": "^10.10.5",
44
45
  "react": "^18.3.1",
45
46
  "tiny-secp256k1": "^2.2.3"
46
47
  }
47
- }
48
+ }