ryt-sdk 1.0.8 → 1.0.10

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/dist/config.d.ts CHANGED
@@ -1,39 +1,102 @@
1
- /**
2
- * Configuration options for initializing the RYT SDK
3
- */
4
1
  export interface SDKConfig {
5
2
  /**
6
- * Chain ID of the target blockchain network
7
- * @example 1 (Ethereum Mainnet), 137 (Polygon)
3
+ * Chain ID of the target blockchain network.
4
+ *
5
+ * This determines which network the SDK will interact with.
6
+ * Must match the EVM chain ID of the connected network.
7
+ *
8
+ * @example 1 (Ethereum Mainnet)
9
+ * @example 137 (Polygon)
10
+ * @example 247 (Custom testnet)
8
11
  */
9
12
  chainId: number;
10
13
  /**
11
- * List of RPC endpoints used to communicate with the blockchain
12
- * The SDK may use fallback logic if multiple URLs are provided
13
- * @example ["https://rpc1.example.com", "https://rpc2.example.com"]
14
+ * List of RPC endpoints used for blockchain communication.
15
+ *
16
+ * - Required in Node.js environments
17
+ * - Used as fallback when no injected wallet is available in browser
18
+ * - The SDK may try multiple URLs for redundancy
19
+ *
20
+ * @example
21
+ * ["https://rpc1.example.com", "https://rpc2.example.com"]
14
22
  */
15
- rpcUrls: string[];
23
+ rpcUrls?: string[];
16
24
  /**
17
- * Optional block explorer base URL for the network
18
- * Used to generate transaction/address links if provided
25
+ * Optional block explorer base URL.
26
+ *
27
+ * Used to generate transaction or address links in UI.
28
+ *
19
29
  * @example "https://etherscan.io"
30
+ * @example "https://polygonscan.com"
20
31
  */
21
32
  explorer?: string;
33
+ /**
34
+ * Enables browser wallet support.
35
+ *
36
+ * If enabled, SDK will attempt to use:
37
+ * - window.ethereum (MetaMask, Rabby, etc.)
38
+ *
39
+ * If disabled, SDK will strictly use RPC provider.
40
+ *
41
+ * @default true
42
+ */
43
+ enableBrowserWallet?: boolean;
44
+ /**
45
+ * Prefer injected wallet provider (window.ethereum) over RPC.
46
+ *
47
+ * When true:
48
+ * - Browser wallets are prioritized
49
+ * - RPC is used only as fallback
50
+ *
51
+ * @default true
52
+ */
53
+ preferInjectedProvider?: boolean;
22
54
  }
23
55
  /**
24
- * Validates and normalizes SDK configuration
56
+ * Detects whether the SDK is running in a browser environment.
57
+ *
58
+ * This is used internally to:
59
+ * - Choose between injected wallet vs RPC provider
60
+ * - Prevent Node-only logic from running in frontend
61
+ *
62
+ * @returns {boolean}
63
+ * true if running in browser AND MetaMask (or injected wallet) is available
64
+ *
65
+ * @example
66
+ * if (isBrowser()) {
67
+ * console.log("Running in frontend dApp mode");
68
+ * }
69
+ */
70
+ export declare function isBrowser(): boolean;
71
+ /**
72
+ * Validates and normalizes SDK configuration.
73
+ *
74
+ * This function ensures:
75
+ * - Required fields are present
76
+ * - Chain ID is valid
77
+ * - RPC URLs are correctly formatted (when required)
78
+ * - Environment-specific rules are enforced
79
+ *
80
+ * It supports both:
81
+ * - Browser dApps (MetaMask / injected wallets)
82
+ * - Node.js backend scripts (RPC only)
83
+ *
84
+ * @param {SDKConfig} config - User-provided SDK configuration
25
85
  *
26
- * @param config - User-provided SDK configuration
27
- * @returns Validated and normalized configuration
86
+ * @returns {SDKConfig} - Normalized and validated configuration
28
87
  *
29
- * @throws Error if required fields are missing or invalid
88
+ * @throws {Error}
89
+ * - If config is missing
90
+ * - If chainId is invalid
91
+ * - If RPC URLs are missing in backend mode
92
+ * - If RPC URLs are malformed
93
+ * - If explorer URL is invalid
30
94
  *
31
95
  * @example
32
- * ```ts
33
96
  * const config = validateConfig({
34
- * chainId: 1234,
35
- * rpcUrls: ["http://localhost:8545"]
97
+ * chainId: 247,
98
+ * rpcUrls: ["https://rpc.testnet.io"],
99
+ * explorer: "https://explorer.testnet.io",
36
100
  * });
37
- * ```
38
101
  */
39
102
  export declare function validateConfig(config: SDKConfig): SDKConfig;
package/dist/config.js CHANGED
@@ -1,18 +1,52 @@
1
+ import { hasRYT } from "./utils/ryt";
1
2
  /**
2
- * Validates and normalizes SDK configuration
3
+ * Detects whether the SDK is running in a browser environment.
3
4
  *
4
- * @param config - User-provided SDK configuration
5
- * @returns Validated and normalized configuration
5
+ * This is used internally to:
6
+ * - Choose between injected wallet vs RPC provider
7
+ * - Prevent Node-only logic from running in frontend
6
8
  *
7
- * @throws Error if required fields are missing or invalid
9
+ * @returns {boolean}
10
+ * true if running in browser AND MetaMask (or injected wallet) is available
11
+ *
12
+ * @example
13
+ * if (isBrowser()) {
14
+ * console.log("Running in frontend dApp mode");
15
+ * }
16
+ */
17
+ export function isBrowser() {
18
+ return typeof window !== "undefined";
19
+ }
20
+ /**
21
+ * Validates and normalizes SDK configuration.
22
+ *
23
+ * This function ensures:
24
+ * - Required fields are present
25
+ * - Chain ID is valid
26
+ * - RPC URLs are correctly formatted (when required)
27
+ * - Environment-specific rules are enforced
28
+ *
29
+ * It supports both:
30
+ * - Browser dApps (MetaMask / injected wallets)
31
+ * - Node.js backend scripts (RPC only)
32
+ *
33
+ * @param {SDKConfig} config - User-provided SDK configuration
34
+ *
35
+ * @returns {SDKConfig} - Normalized and validated configuration
36
+ *
37
+ * @throws {Error}
38
+ * - If config is missing
39
+ * - If chainId is invalid
40
+ * - If RPC URLs are missing in backend mode
41
+ * - If RPC URLs are malformed
42
+ * - If explorer URL is invalid
8
43
  *
9
44
  * @example
10
- * ```ts
11
45
  * const config = validateConfig({
12
- * chainId: 1234,
13
- * rpcUrls: ["http://localhost:8545"]
46
+ * chainId: 247,
47
+ * rpcUrls: ["https://rpc.testnet.io"],
48
+ * explorer: "https://explorer.testnet.io",
14
49
  * });
15
- * ```
16
50
  */
17
51
  export function validateConfig(config) {
18
52
  if (!config) {
@@ -21,17 +55,49 @@ export function validateConfig(config) {
21
55
  if (typeof config.chainId !== "number" || isNaN(config.chainId)) {
22
56
  throw new Error("Invalid chainId: must be a valid number");
23
57
  }
24
- if (!Array.isArray(config.rpcUrls) || config.rpcUrls.length === 0) {
25
- throw new Error("rpcUrls must be a non-empty array");
58
+ const enableBrowserWallet = config.enableBrowserWallet ?? true;
59
+ const preferInjectedProvider = config.preferInjectedProvider ?? true;
60
+ /**
61
+ * -----------------------------
62
+ * Frontend (Browser) validation
63
+ * -----------------------------
64
+ * Ensures at least one provider is available:
65
+ * - MetaMask (window.ethereum)
66
+ * - OR RPC fallback
67
+ */
68
+ if (isBrowser() && enableBrowserWallet) {
69
+ if (!hasRYT() && (!config.rpcUrls || config.rpcUrls.length === 0)) {
70
+ throw new Error("No injected wallet detected and no RPC fallback provided");
71
+ }
26
72
  }
27
- for (const url of config.rpcUrls) {
28
- if (typeof url !== "string" || !url.startsWith("http")) {
29
- throw new Error(`Invalid RPC URL: ${url}`);
73
+ /**
74
+ * -----------------------------
75
+ * Backend validation (Node.js)
76
+ * -----------------------------
77
+ * RPC is mandatory in backend mode.
78
+ */
79
+ if (!isBrowser()) {
80
+ if (!config.rpcUrls || config.rpcUrls.length === 0) {
81
+ throw new Error("rpcUrls are required in backend mode");
82
+ }
83
+ for (const url of config.rpcUrls) {
84
+ if (typeof url !== "string" || !url.startsWith("http")) {
85
+ throw new Error(`Invalid RPC URL: ${url}`);
86
+ }
30
87
  }
31
88
  }
32
- if (config.explorer !== undefined &&
33
- (typeof config.explorer !== "string" || config.explorer.length === 0)) {
34
- throw new Error("explorer must be a valid URL string if provided");
89
+ /**
90
+ * Explorer validation (optional field)
91
+ */
92
+ if (config.explorer &&
93
+ (typeof config.explorer !== "string" || config.explorer.length < 5)) {
94
+ throw new Error("Invalid explorer URL");
35
95
  }
36
- return config;
96
+ return {
97
+ chainId: config.chainId,
98
+ rpcUrls: config.rpcUrls,
99
+ explorer: config.explorer,
100
+ enableBrowserWallet,
101
+ preferInjectedProvider,
102
+ };
37
103
  }
@@ -67,7 +67,9 @@ export interface LibraryDeployOptions {
67
67
  * ----------------------------------------------------
68
68
  *
69
69
  * Supports:
70
- * - Read / Write contract calls
70
+ * - Read / Write contract calls (frontend + backend)
71
+ * - Browser wallet interactions (MetaMask, injected wallets)
72
+ * - Server-side wallet usage (private key)
71
73
  * - CREATE deployment
72
74
  * - CREATE2 deployment
73
75
  * - Minimal proxy (EIP-1167)
@@ -80,23 +82,32 @@ export default class RYTContract {
80
82
  /**
81
83
  * Create a new contract instance
82
84
  *
85
+ * Works in:
86
+ * - Browser (injected wallet signer)
87
+ * - Backend (private key wallet)
88
+ * - Read-only mode (RPC provider)
89
+ *
83
90
  * @param address - deployed contract address (optional)
84
91
  * @param abi - contract ABI
85
- * @param signerOrProvider - wallet or provider instance
92
+ * @param signerOrProvider - wallet, signer or provider
86
93
  */
87
- constructor(address: string | null, abi: any[], signerOrProvider: RYTWallet | ethers.Provider | any);
94
+ constructor(address: string | null, abi: any[], signerOrProvider: RYTWallet | ethers.Signer | ethers.Provider | any);
88
95
  /**
89
96
  * Call a read-only contract method
90
97
  *
91
- * @param method - contract function name
98
+ * @param method - function name
92
99
  * @param params - function arguments
93
- * @returns result of contract call
100
+ * @returns contract result
94
101
  */
95
102
  read(method: string, ...params: any[]): Promise<any>;
96
103
  /**
97
104
  * Call a state-changing contract method
98
105
  *
99
- * @param method - contract function name
106
+ * Works with:
107
+ * - MetaMask / browser wallets
108
+ * - Backend private key wallets
109
+ *
110
+ * @param method - function name
100
111
  * @param params - function arguments
101
112
  * @returns transaction response
102
113
  */
@@ -104,7 +115,7 @@ export default class RYTContract {
104
115
  /**
105
116
  * Deploy a contract using CREATE opcode
106
117
  *
107
- * @param options - deployment options
118
+ * @param options - deployment options (Requires signer (browser or backend wallet))
108
119
  * @returns updated contract instance
109
120
  */
110
121
  deploy(options: DeployOptions): Promise<this>;
package/dist/contract.js CHANGED
@@ -5,11 +5,6 @@ import ERC1967Proxy from "@openzeppelin/contracts/build/contracts/ERC1967Proxy.j
5
5
  * -----------------------------
6
6
  * Internal helper: Link libraries into bytecode
7
7
  * -----------------------------
8
- *
9
- * @param bytecode - raw contract bytecode
10
- * @param linkReferences - compiler link references
11
- * @param libraries - deployed library addresses
12
- * @returns linked bytecode string
13
8
  */
14
9
  async function linkLibraries(bytecode, linkReferences, libraries) {
15
10
  let linked = bytecode.startsWith("0x") ? bytecode.slice(2) : bytecode;
@@ -34,7 +29,7 @@ async function linkLibraries(bytecode, linkReferences, libraries) {
34
29
  linked =
35
30
  linked.slice(0, start * 2) +
36
31
  address.padStart(length * 2, "0") +
37
- linked.slice((start + length) * 2);
32
+ linked.slice((start + (length - 1)) * 2);
38
33
  }
39
34
  return linked;
40
35
  }
@@ -44,7 +39,9 @@ async function linkLibraries(bytecode, linkReferences, libraries) {
44
39
  * ----------------------------------------------------
45
40
  *
46
41
  * Supports:
47
- * - Read / Write contract calls
42
+ * - Read / Write contract calls (frontend + backend)
43
+ * - Browser wallet interactions (MetaMask, injected wallets)
44
+ * - Server-side wallet usage (private key)
48
45
  * - CREATE deployment
49
46
  * - CREATE2 deployment
50
47
  * - Minimal proxy (EIP-1167)
@@ -55,15 +52,24 @@ export default class RYTContract {
55
52
  /**
56
53
  * Create a new contract instance
57
54
  *
55
+ * Works in:
56
+ * - Browser (injected wallet signer)
57
+ * - Backend (private key wallet)
58
+ * - Read-only mode (RPC provider)
59
+ *
58
60
  * @param address - deployed contract address (optional)
59
61
  * @param abi - contract ABI
60
- * @param signerOrProvider - wallet or provider instance
62
+ * @param signerOrProvider - wallet, signer or provider
61
63
  */
62
64
  constructor(address, abi, signerOrProvider) {
63
- this.wallet = signerOrProvider instanceof RYTWallet ? signerOrProvider : null;
65
+ this.wallet =
66
+ signerOrProvider instanceof RYTWallet ? signerOrProvider : null;
64
67
  const provider = signerOrProvider?.getProvider?.() || signerOrProvider;
68
+ const signer = signerOrProvider instanceof RYTWallet
69
+ ? signerOrProvider.getSigner()
70
+ : signerOrProvider;
65
71
  this.contract = address
66
- ? new ethers.Contract(address, abi, this.wallet ? this.wallet["wallet"] : provider)
72
+ ? new ethers.Contract(address, abi, signer ?? provider)
67
73
  : null;
68
74
  }
69
75
  // ----------------------------------------------------
@@ -72,9 +78,9 @@ export default class RYTContract {
72
78
  /**
73
79
  * Call a read-only contract method
74
80
  *
75
- * @param method - contract function name
81
+ * @param method - function name
76
82
  * @param params - function arguments
77
- * @returns result of contract call
83
+ * @returns contract result
78
84
  */
79
85
  read(method, ...params) {
80
86
  if (!this.contract)
@@ -84,7 +90,11 @@ export default class RYTContract {
84
90
  /**
85
91
  * Call a state-changing contract method
86
92
  *
87
- * @param method - contract function name
93
+ * Works with:
94
+ * - MetaMask / browser wallets
95
+ * - Backend private key wallets
96
+ *
97
+ * @param method - function name
88
98
  * @param params - function arguments
89
99
  * @returns transaction response
90
100
  */
@@ -99,16 +109,15 @@ export default class RYTContract {
99
109
  /**
100
110
  * Deploy a contract using CREATE opcode
101
111
  *
102
- * @param options - deployment options
112
+ * @param options - deployment options (Requires signer (browser or backend wallet))
103
113
  * @returns updated contract instance
104
114
  */
105
115
  async deploy(options) {
106
116
  if (!this.wallet)
107
117
  throw new Error("Wallet required for deploy");
108
- const factory = new ethers.ContractFactory(options.abi, options.bytecode, this.wallet["wallet"]);
109
- const contract = await factory.deploy(...(options.args ?? []), {
110
- value: options.value ?? 0,
111
- });
118
+ const signer = this.wallet["getSigner"]?.() || this.wallet.getSigner();
119
+ const factory = new ethers.ContractFactory(options.abi, options.bytecode, signer);
120
+ const contract = await factory.deploy(...(options.args ?? []), { value: options.value ?? 0 });
112
121
  await contract.waitForDeployment();
113
122
  this.contract = contract;
114
123
  return this;
@@ -125,6 +134,7 @@ export default class RYTContract {
125
134
  async deployCreate2(options) {
126
135
  if (!this.wallet)
127
136
  throw new Error("Wallet required for deployCreate2");
137
+ const signer = this.wallet["getSigner"]?.() || this.wallet.getSigner();
128
138
  const encodedArgs = options.args && options.args.length > 0
129
139
  ? new ethers.Interface(options.abi).encodeDeploy(options.args)
130
140
  : "0x";
@@ -134,13 +144,11 @@ export default class RYTContract {
134
144
  ]);
135
145
  const factory = new ethers.Contract(options.factoryAddress, [
136
146
  "function deploy(bytes32 salt, bytes code) external payable returns (address)",
137
- ], this.wallet["wallet"]);
147
+ ], signer);
138
148
  const addr = ethers.getCreate2Address(options.factoryAddress, options.salt, ethers.keccak256(creationCode));
139
- const tx = options.value && options.value > 0
140
- ? await factory.deploy(options.salt, creationCode, {
141
- value: options.value,
142
- })
143
- : await factory.deploy(options.salt, creationCode);
149
+ const tx = await factory.deploy(options.salt, creationCode, {
150
+ value: options.value ?? 0,
151
+ });
144
152
  return {
145
153
  receipt: await tx.wait(),
146
154
  contractHash: addr,
@@ -158,13 +166,12 @@ export default class RYTContract {
158
166
  async deployClone(implementationAddress) {
159
167
  if (!this.wallet)
160
168
  throw new Error("Wallet required for deployClone");
169
+ const signer = this.wallet["getSigner"]?.() || this.wallet.getSigner();
161
170
  const bytecode = "0x3d602d80600a3d3981f3" +
162
171
  "363d3d373d3d3d363d73" +
163
172
  implementationAddress.slice(2) +
164
173
  "5af43d82803e903d91602b57fd5bf3";
165
- const tx = await this.wallet["wallet"].sendTransaction({
166
- data: bytecode,
167
- });
174
+ const tx = await signer.sendTransaction({ data: bytecode });
168
175
  return await tx.wait();
169
176
  }
170
177
  // ----------------------------------------------------
@@ -179,17 +186,18 @@ export default class RYTContract {
179
186
  async deployUUPS(options) {
180
187
  if (!this.wallet)
181
188
  throw new Error("Wallet required for deployUUPS");
182
- const implFactory = new ethers.ContractFactory(options.implementationAbi, options.implementationBytecode, this.wallet["wallet"]);
189
+ const signer = this.wallet["getSigner"]?.() || this.wallet.getSigner();
190
+ const implFactory = new ethers.ContractFactory(options.implementationAbi, options.implementationBytecode, signer);
183
191
  const impl = await implFactory.deploy();
184
192
  await impl.waitForDeployment();
185
193
  const implAddress = impl.target;
186
- const proxyFactory = new ethers.ContractFactory(ERC1967Proxy.abi, ERC1967Proxy.bytecode, this.wallet["wallet"]);
194
+ const proxyFactory = new ethers.ContractFactory(ERC1967Proxy.abi, ERC1967Proxy.bytecode, signer);
187
195
  const proxy = await proxyFactory.deploy(implAddress, options.initData ?? "0x");
188
196
  await proxy.waitForDeployment();
189
197
  return new RYTContract(proxy.target, options.implementationAbi, this.wallet);
190
198
  }
191
199
  // ----------------------------------------------------
192
- // Library-linked deployment
200
+ // Library-linked deployment (UNCHANGED STYLE)
193
201
  // ----------------------------------------------------
194
202
  /**
195
203
  * Deploy contract with Solidity libraries linked
package/dist/index.d.ts CHANGED
@@ -1,38 +1,77 @@
1
+ import { getRYT, hasRYT, requestAccounts } from "./utils/ryt";
2
+ export { parseTokenUnits, formatTokenUnits } from "./utils/units";
1
3
  /**
2
4
  * ------------------------------------------------------
3
5
  * RYT SDK - Public Entry Point
4
6
  * ------------------------------------------------------
5
7
  *
6
- * This file exposes the main SDK modules:
7
- * - Provider (RPC layer)
8
- * - Wallet (signing layer)
9
- * - Contract (smart contract interaction layer)
8
+ * Exposes core SDK modules for:
9
+ * - Blockchain interaction (Provider)
10
+ * - Wallet management (Wallet)
11
+ * - Smart contracts (Contract layer)
10
12
  *
11
- * This is the ONLY file users should import from:
12
- *
13
- * @example
14
- * ```ts
15
- * import { RYTProvider, RYTWallet, RYTContract } from "ryt-sdk";
16
- * ```
13
+ * Works in:
14
+ * - Browser (MetaMask / injected wallets)
15
+ * - Node.js (RPC-based flows)
17
16
  */
18
17
  /**
19
- * Provider module for RPC interactions
18
+ * ------------------------------------------------------
19
+ * Core Modules
20
+ * ------------------------------------------------------
20
21
  */
21
22
  export { default as RYTProvider } from "./provider";
23
+ export { default as RYTWallet } from "./wallet";
24
+ export { default as RYTContract } from "./contract";
22
25
  /**
23
- * Wallet module for signing transactions
26
+ * ------------------------------------------------------
27
+ * Browser / Wallet Utilities
28
+ * ------------------------------------------------------
24
29
  */
25
- export { default as RYTWallet } from "./wallet";
26
30
  /**
27
- * Contract module for smart contract interactions
31
+ * Gets injected wallet provider (MetaMask, Rabby, etc.)
32
+ *
33
+ * @returns EIP-1193 provider or undefined
34
+ *
35
+ * @example
36
+ * const provider = getRYT();
28
37
  */
29
- export { default as RYTContract } from "./contract";
38
+ export { getRYT };
39
+ /**
40
+ * Checks if injected wallet is available in browser.
41
+ *
42
+ * @returns true if wallet is detected
43
+ *
44
+ * @example
45
+ * if (hasRYT()) console.log("Wallet ready");
46
+ */
47
+ export { hasRYT };
48
+ /**
49
+ * Requests wallet connection (opens MetaMask popup).
50
+ *
51
+ * @returns list of connected addresses
52
+ *
53
+ * @example
54
+ * const accounts = await requestAccounts();
55
+ */
56
+ export { requestAccounts };
30
57
  /**
31
58
  * ------------------------------------------------------
32
- * Optional: Future unified SDK export (recommended)
59
+ * Convenience helpers (SDK-level safe checks)
33
60
  * ------------------------------------------------------
61
+ */
62
+ /**
63
+ * Checks if running in browser environment.
34
64
  *
35
- * Uncomment when you want a single entry API:
65
+ * @returns true if window is available
66
+ */
67
+ export declare const isBrowser: () => boolean;
68
+ /**
69
+ * Checks if wallet is ready for use.
70
+ *
71
+ * Combines:
72
+ * - browser check
73
+ * - injected wallet check
36
74
  *
37
- * export { default as RYTClient } from "./client";
38
- */
75
+ * @returns true if wallet can be used
76
+ */
77
+ export declare const isWalletAvailable: () => boolean;
package/dist/index.js CHANGED
@@ -1,38 +1,81 @@
1
+ import { getRYT, hasRYT, requestAccounts } from "./utils/ryt";
2
+ export { parseTokenUnits, formatTokenUnits } from "./utils/units";
1
3
  /**
2
4
  * ------------------------------------------------------
3
5
  * RYT SDK - Public Entry Point
4
6
  * ------------------------------------------------------
5
7
  *
6
- * This file exposes the main SDK modules:
7
- * - Provider (RPC layer)
8
- * - Wallet (signing layer)
9
- * - Contract (smart contract interaction layer)
8
+ * Exposes core SDK modules for:
9
+ * - Blockchain interaction (Provider)
10
+ * - Wallet management (Wallet)
11
+ * - Smart contracts (Contract layer)
10
12
  *
11
- * This is the ONLY file users should import from:
12
- *
13
- * @example
14
- * ```ts
15
- * import { RYTProvider, RYTWallet, RYTContract } from "ryt-sdk";
16
- * ```
13
+ * Works in:
14
+ * - Browser (MetaMask / injected wallets)
15
+ * - Node.js (RPC-based flows)
17
16
  */
18
17
  /**
19
- * Provider module for RPC interactions
18
+ * ------------------------------------------------------
19
+ * Core Modules
20
+ * ------------------------------------------------------
20
21
  */
21
22
  export { default as RYTProvider } from "./provider";
23
+ export { default as RYTWallet } from "./wallet";
24
+ export { default as RYTContract } from "./contract";
22
25
  /**
23
- * Wallet module for signing transactions
26
+ * ------------------------------------------------------
27
+ * Browser / Wallet Utilities
28
+ * ------------------------------------------------------
24
29
  */
25
- export { default as RYTWallet } from "./wallet";
26
30
  /**
27
- * Contract module for smart contract interactions
31
+ * Gets injected wallet provider (MetaMask, Rabby, etc.)
32
+ *
33
+ * @returns EIP-1193 provider or undefined
34
+ *
35
+ * @example
36
+ * const provider = getRYT();
28
37
  */
29
- export { default as RYTContract } from "./contract";
38
+ export { getRYT };
39
+ /**
40
+ * Checks if injected wallet is available in browser.
41
+ *
42
+ * @returns true if wallet is detected
43
+ *
44
+ * @example
45
+ * if (hasRYT()) console.log("Wallet ready");
46
+ */
47
+ export { hasRYT };
48
+ /**
49
+ * Requests wallet connection (opens MetaMask popup).
50
+ *
51
+ * @returns list of connected addresses
52
+ *
53
+ * @example
54
+ * const accounts = await requestAccounts();
55
+ */
56
+ export { requestAccounts };
30
57
  /**
31
58
  * ------------------------------------------------------
32
- * Optional: Future unified SDK export (recommended)
59
+ * Convenience helpers (SDK-level safe checks)
33
60
  * ------------------------------------------------------
61
+ */
62
+ /**
63
+ * Checks if running in browser environment.
34
64
  *
35
- * Uncomment when you want a single entry API:
65
+ * @returns true if window is available
66
+ */
67
+ export const isBrowser = () => {
68
+ return typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
69
+ };
70
+ /**
71
+ * Checks if wallet is ready for use.
72
+ *
73
+ * Combines:
74
+ * - browser check
75
+ * - injected wallet check
36
76
  *
37
- * export { default as RYTClient } from "./client";
38
- */
77
+ * @returns true if wallet can be used
78
+ */
79
+ export const isWalletAvailable = () => {
80
+ return isBrowser() && hasRYT();
81
+ };