@frontiertower/frontier-sdk 0.1.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.
package/dist/index.mjs ADDED
@@ -0,0 +1,449 @@
1
+ // src/access/wallet.ts
2
+ var WalletAccess = class {
3
+ constructor(sdk) {
4
+ this.sdk = sdk;
5
+ }
6
+ /**
7
+ * Get the current wallet balance
8
+ *
9
+ * Returns the total USD stablecoin balance for the current network,
10
+ * normalized to 18 decimals for consistency.
11
+ *
12
+ * @returns Balance as bigint (18 decimals)
13
+ * @throws {Error} If no wallet exists
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const balance = await sdk.getWallet().getBalance();
18
+ * console.log('Balance:', balance.toString());
19
+ * ```
20
+ */
21
+ async getBalance() {
22
+ return this.sdk.request("wallet:getBalance");
23
+ }
24
+ /**
25
+ * Get the current wallet balance formatted for display
26
+ *
27
+ * Returns the total USD stablecoin balance as a formatted string
28
+ * with currency symbol (e.g., '$10.50').
29
+ *
30
+ * @returns Formatted balance string with $ sign
31
+ * @throws {Error} If no wallet exists
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const balance = await sdk.getWallet().getBalanceFormatted();
36
+ * console.log('Balance:', balance); // '$10.50'
37
+ * ```
38
+ */
39
+ async getBalanceFormatted() {
40
+ return this.sdk.request("wallet:getBalanceFormatted");
41
+ }
42
+ /**
43
+ * Get the wallet address for the current network
44
+ *
45
+ * Returns the smart account contract address for the current chain.
46
+ *
47
+ * @returns The wallet address as a hex string
48
+ * @throws {Error} If no wallet exists
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const address = await sdk.getWallet().getAddress();
53
+ * console.log('Address:', address);
54
+ * ```
55
+ */
56
+ async getAddress() {
57
+ return this.sdk.request("wallet:getAddress");
58
+ }
59
+ /**
60
+ * Get smart account for the current network
61
+ *
62
+ * Returns detailed information about the smart account including
63
+ * deployment status and network information.
64
+ *
65
+ * @returns Smart account information
66
+ * @throws {Error} If no smart account found for current network
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const account = await sdk.getWallet().getSmartAccount();
71
+ * console.log('Contract address:', account.contractAddress);
72
+ * console.log('Network:', account.network);
73
+ * ```
74
+ */
75
+ async getSmartAccount() {
76
+ return this.sdk.request("wallet:getSmartAccount");
77
+ }
78
+ /**
79
+ * Transfer ERC20 tokens
80
+ *
81
+ * Sends ERC20 tokens to a recipient address using the current network.
82
+ * Requires biometric authentication and sufficient balance.
83
+ *
84
+ * @param tokenAddress - ERC20 token contract address
85
+ * @param to - Recipient address
86
+ * @param amount - Amount to send (in token's smallest unit, e.g., wei)
87
+ * @param overrides - Optional gas overrides
88
+ * @returns User operation receipt with transaction details
89
+ * @throws {Error} If insufficient balance or transaction fails
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * import { parseUnits } from 'viem';
94
+ *
95
+ * const receipt = await sdk.getWallet().transferERC20(
96
+ * '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238', // USDC on Sepolia
97
+ * '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
98
+ * parseUnits('10.5', 6) // 10.5 USDC (6 decimals)
99
+ * );
100
+ * console.log('Transaction:', receipt.transactionHash);
101
+ * ```
102
+ */
103
+ async transferERC20(tokenAddress, to, amount, overrides) {
104
+ return this.sdk.request("wallet:transferERC20", {
105
+ tokenAddress,
106
+ to,
107
+ amount,
108
+ overrides
109
+ });
110
+ }
111
+ /**
112
+ * Approve ERC20 tokens for spending
113
+ *
114
+ * Approves a spender to transfer tokens on your behalf.
115
+ * Required before interacting with DeFi protocols.
116
+ *
117
+ * @param tokenAddress - ERC20 token contract address
118
+ * @param spender - Address allowed to spend tokens
119
+ * @param amount - Amount to approve (in token's smallest unit)
120
+ * @param overrides - Optional gas overrides
121
+ * @returns User operation receipt with transaction details
122
+ * @throws {Error} If transaction fails
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * import { parseUnits } from 'viem';
127
+ *
128
+ * const receipt = await sdk.getWallet().approveERC20(
129
+ * '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238', // USDC
130
+ * '0xProtocolAddress',
131
+ * parseUnits('100', 6) // Approve 100 USDC
132
+ * );
133
+ * ```
134
+ */
135
+ async approveERC20(tokenAddress, spender, amount, overrides) {
136
+ return this.sdk.request("wallet:approveERC20", {
137
+ tokenAddress,
138
+ spender,
139
+ amount,
140
+ overrides
141
+ });
142
+ }
143
+ /**
144
+ * Transfer native currency (ETH)
145
+ *
146
+ * Sends native currency to a recipient address.
147
+ * Requires biometric authentication and sufficient balance.
148
+ *
149
+ * @param to - Recipient address
150
+ * @param amount - Amount to send in wei
151
+ * @param overrides - Optional gas overrides
152
+ * @returns User operation receipt with transaction details
153
+ * @throws {Error} If insufficient balance or transaction fails
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * import { parseEther } from 'viem';
158
+ *
159
+ * const receipt = await sdk.getWallet().transferNative(
160
+ * '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
161
+ * parseEther('0.1') // 0.1 ETH
162
+ * );
163
+ * ```
164
+ */
165
+ async transferNative(to, amount, overrides) {
166
+ return this.sdk.request("wallet:transferNative", {
167
+ to,
168
+ amount,
169
+ overrides
170
+ });
171
+ }
172
+ /**
173
+ * Execute arbitrary contract call
174
+ *
175
+ * Executes a custom contract interaction with full control over
176
+ * the target address, value, and calldata.
177
+ *
178
+ * @param call - Execute call parameters
179
+ * @param overrides - Optional gas overrides
180
+ * @returns User operation receipt with transaction details
181
+ * @throws {Error} If transaction fails
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * import { encodeFunctionData } from 'viem';
186
+ *
187
+ * const receipt = await sdk.getWallet().executeCall({
188
+ * to: '0xContractAddress',
189
+ * value: 0n,
190
+ * data: encodeFunctionData({
191
+ * abi: contractABI,
192
+ * functionName: 'someFunction',
193
+ * args: [arg1, arg2]
194
+ * })
195
+ * });
196
+ * ```
197
+ */
198
+ async executeCall(call, overrides) {
199
+ return this.sdk.request("wallet:executeCall", {
200
+ call,
201
+ overrides
202
+ });
203
+ }
204
+ };
205
+
206
+ // src/access/storage.ts
207
+ var StorageAccess = class {
208
+ constructor(sdk) {
209
+ this.sdk = sdk;
210
+ }
211
+ /**
212
+ * Get data from persistent storage
213
+ * Requires permission: storage:get or storage:*
214
+ */
215
+ async get(key) {
216
+ return this.sdk.request("storage:get", { key });
217
+ }
218
+ /**
219
+ * Store data persistently
220
+ * Requires permission: storage:set or storage:*
221
+ */
222
+ async set(key, value) {
223
+ return this.sdk.request("storage:set", { key, value });
224
+ }
225
+ /**
226
+ * Remove data from persistent storage
227
+ * Requires permission: storage:remove or storage:*
228
+ */
229
+ async remove(key) {
230
+ return this.sdk.request("storage:remove", { key });
231
+ }
232
+ /**
233
+ * Clear all data from persistent storage
234
+ * Requires permission: storage:clear or storage:*
235
+ */
236
+ async clear() {
237
+ return this.sdk.request("storage:clear");
238
+ }
239
+ };
240
+
241
+ // src/access/chain.ts
242
+ var ChainAccess = class {
243
+ constructor(sdk) {
244
+ this.sdk = sdk;
245
+ }
246
+ /**
247
+ * Get the current network name
248
+ *
249
+ * Returns the network identifier for the currently active chain
250
+ * (e.g., 'base', 'base-sepolia', 'ethereum').
251
+ *
252
+ * @returns Network identifier string
253
+ *
254
+ * @example
255
+ * ```typescript
256
+ * const network = await sdk.getChain().getCurrentNetwork();
257
+ * console.log('Current network:', network); // 'base-sepolia'
258
+ * ```
259
+ */
260
+ async getCurrentNetwork() {
261
+ return this.sdk.request("chain:getCurrentNetwork");
262
+ }
263
+ /**
264
+ * Get all available networks
265
+ *
266
+ * Returns a list of network identifiers that the app can switch to.
267
+ *
268
+ * @returns Array of network identifier strings
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * const networks = await sdk.getChain().getAvailableNetworks();
273
+ * console.log('Available networks:', networks); // ['base', 'base-sepolia']
274
+ * ```
275
+ */
276
+ async getAvailableNetworks() {
277
+ return this.sdk.request("chain:getAvailableNetworks");
278
+ }
279
+ /**
280
+ * Switch to a different network
281
+ *
282
+ * Changes the active blockchain network. This will affect all subsequent
283
+ * wallet operations and contract interactions.
284
+ *
285
+ * @param network - The network identifier to switch to
286
+ * @throws {Error} If the network is not available or switching fails
287
+ *
288
+ * @example
289
+ * ```typescript
290
+ * await sdk.getChain().switchNetwork('base');
291
+ * console.log('Switched to Base mainnet');
292
+ * ```
293
+ */
294
+ async switchNetwork(network) {
295
+ return this.sdk.request("chain:switchNetwork", { network });
296
+ }
297
+ /**
298
+ * Get full chain configuration for current network
299
+ *
300
+ * Returns detailed configuration including chain ID, RPC URLs,
301
+ * block explorer, and native currency information.
302
+ *
303
+ * @returns Complete chain configuration object
304
+ *
305
+ * @example
306
+ * ```typescript
307
+ * const config = await sdk.getChain().getCurrentChainConfig();
308
+ * console.log('Chain ID:', config.id);
309
+ * console.log('Block explorer:', config.blockExplorer.url);
310
+ * ```
311
+ */
312
+ async getCurrentChainConfig() {
313
+ return this.sdk.request("chain:getCurrentChainConfig");
314
+ }
315
+ };
316
+
317
+ // src/access/user.ts
318
+ var UserAccess = class {
319
+ constructor(sdk) {
320
+ this.sdk = sdk;
321
+ }
322
+ /**
323
+ * Get current user details
324
+ *
325
+ * Returns basic information about the currently authenticated user,
326
+ * including their ID, email, and name.
327
+ *
328
+ * @returns User object with basic information
329
+ * @throws {Error} If user is not authenticated
330
+ *
331
+ * @example
332
+ * ```typescript
333
+ * const user = await sdk.getUser().getDetails();
334
+ * console.log('User email:', user.email);
335
+ * console.log('User name:', `${user.firstName} ${user.lastName}`);
336
+ * ```
337
+ */
338
+ async getDetails() {
339
+ return this.sdk.request("user:getDetails");
340
+ }
341
+ /**
342
+ * Get user profile by ID
343
+ *
344
+ * Returns detailed profile information for a specific user,
345
+ * including social media handles, preferences, and community information.
346
+ *
347
+ * @param id - The profile ID to fetch
348
+ * @returns UserProfile object with detailed information
349
+ * @throws {Error} If profile is not found or access is denied
350
+ *
351
+ * @example
352
+ * ```typescript
353
+ * const profile = await sdk.getUser().getProfile(123);
354
+ * console.log('Nickname:', profile.nickname);
355
+ * console.log('GitHub:', profile.githubHandle);
356
+ * console.log('Community:', profile.communityName);
357
+ * ```
358
+ */
359
+ async getProfile(id) {
360
+ return this.sdk.request("user:getProfile", { id });
361
+ }
362
+ };
363
+
364
+ // src/sdk.ts
365
+ var FrontierSDK = class {
366
+ constructor() {
367
+ this.requestId = 0;
368
+ this.pendingRequests = /* @__PURE__ */ new Map();
369
+ this.handleMessage = (event) => {
370
+ if (event.source !== window.parent) return;
371
+ const response = event.data;
372
+ const pending = this.pendingRequests.get(response.requestId);
373
+ if (pending) {
374
+ if (response.type === "error") {
375
+ pending.reject(new Error(response.error));
376
+ } else {
377
+ pending.resolve(response.result);
378
+ }
379
+ this.pendingRequests.delete(response.requestId);
380
+ }
381
+ };
382
+ this.wallet = new WalletAccess(this);
383
+ this.storage = new StorageAccess(this);
384
+ this.chain = new ChainAccess(this);
385
+ this.user = new UserAccess(this);
386
+ window.addEventListener("message", this.handleMessage);
387
+ this.notifyReady();
388
+ }
389
+ /**
390
+ * Internal request method used by access classes
391
+ * @internal
392
+ */
393
+ request(type, payload) {
394
+ return new Promise((resolve, reject) => {
395
+ const requestId = `${Date.now()}-${this.requestId++}`;
396
+ this.pendingRequests.set(requestId, { resolve, reject });
397
+ const request = { type, requestId, payload };
398
+ window.parent.postMessage(request, "*");
399
+ setTimeout(() => {
400
+ if (this.pendingRequests.has(requestId)) {
401
+ this.pendingRequests.delete(requestId);
402
+ reject(new Error("Request timeout"));
403
+ }
404
+ }, 3e4);
405
+ });
406
+ }
407
+ notifyReady() {
408
+ window.parent.postMessage({ type: "app:ready", payload: null }, "*");
409
+ }
410
+ /**
411
+ * Get wallet access instance
412
+ */
413
+ getWallet() {
414
+ return this.wallet;
415
+ }
416
+ /**
417
+ * Get storage access instance
418
+ */
419
+ getStorage() {
420
+ return this.storage;
421
+ }
422
+ /**
423
+ * Get chain access instance
424
+ */
425
+ getChain() {
426
+ return this.chain;
427
+ }
428
+ /**
429
+ * Get user access instance
430
+ */
431
+ getUser() {
432
+ return this.user;
433
+ }
434
+ /**
435
+ * Cleanup: Remove event listeners
436
+ * Call this when your app is being destroyed
437
+ */
438
+ destroy() {
439
+ window.removeEventListener("message", this.handleMessage);
440
+ this.pendingRequests.clear();
441
+ }
442
+ };
443
+ export {
444
+ ChainAccess,
445
+ FrontierSDK,
446
+ StorageAccess,
447
+ UserAccess,
448
+ WalletAccess
449
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Check if the app is running inside a Frontier Wallet iframe
3
+ * Verifies both that it's in an iframe and that the parent origin is allowed
4
+ */
5
+ declare function isInFrontierApp(): boolean;
6
+ /**
7
+ * Get the parent Frontier Wallet origin if available
8
+ */
9
+ declare function getParentOrigin(): string | null;
10
+
11
+ /**
12
+ * Render a standalone message when app is not running in Frontier Wallet
13
+ * @param container - The HTML element to render into
14
+ * @param appName - Optional custom app name (defaults to "Frontier App")
15
+ */
16
+ declare function renderStandaloneMessage(container: HTMLElement, appName?: string): void;
17
+ /**
18
+ * Create a standalone message element (returns HTML string)
19
+ * @param appName - Optional custom app name (defaults to "Frontier App")
20
+ */
21
+ declare function createStandaloneHTML(appName?: string): string;
22
+
23
+ export { createStandaloneHTML, getParentOrigin, isInFrontierApp, renderStandaloneMessage };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Check if the app is running inside a Frontier Wallet iframe
3
+ * Verifies both that it's in an iframe and that the parent origin is allowed
4
+ */
5
+ declare function isInFrontierApp(): boolean;
6
+ /**
7
+ * Get the parent Frontier Wallet origin if available
8
+ */
9
+ declare function getParentOrigin(): string | null;
10
+
11
+ /**
12
+ * Render a standalone message when app is not running in Frontier Wallet
13
+ * @param container - The HTML element to render into
14
+ * @param appName - Optional custom app name (defaults to "Frontier App")
15
+ */
16
+ declare function renderStandaloneMessage(container: HTMLElement, appName?: string): void;
17
+ /**
18
+ * Create a standalone message element (returns HTML string)
19
+ * @param appName - Optional custom app name (defaults to "Frontier App")
20
+ */
21
+ declare function createStandaloneHTML(appName?: string): string;
22
+
23
+ export { createStandaloneHTML, getParentOrigin, isInFrontierApp, renderStandaloneMessage };