frontier-os-app-builder 1.0.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/README.md +92 -0
- package/agents/fos-executor.md +460 -0
- package/agents/fos-plan-checker.md +386 -0
- package/agents/fos-planner.md +416 -0
- package/agents/fos-researcher.md +358 -0
- package/agents/fos-verifier.md +491 -0
- package/bin/fos-tools.cjs +794 -0
- package/bin/install.js +234 -0
- package/commands/fos/add-feature.md +29 -0
- package/commands/fos/discuss.md +31 -0
- package/commands/fos/execute.md +35 -0
- package/commands/fos/new-app.md +39 -0
- package/commands/fos/new-milestone.md +28 -0
- package/commands/fos/next.md +29 -0
- package/commands/fos/plan.md +37 -0
- package/commands/fos/ship.md +29 -0
- package/commands/fos/status.md +22 -0
- package/package.json +30 -0
- package/references/app-patterns.md +501 -0
- package/references/deployment.md +395 -0
- package/references/module-inference.md +349 -0
- package/references/sdk-surface.md +1622 -0
- package/references/verification-rules.md +404 -0
- package/templates/app/gitignore +25 -0
- package/templates/app/index.css +111 -0
- package/templates/app/index.html +19 -0
- package/templates/app/layout.tsx +45 -0
- package/templates/app/main-router.tsx +17 -0
- package/templates/app/main-simple.tsx +19 -0
- package/templates/app/package.json +36 -0
- package/templates/app/postcss.config.js +5 -0
- package/templates/app/router.tsx +22 -0
- package/templates/app/sdk-context.tsx +33 -0
- package/templates/app/test-setup.ts +19 -0
- package/templates/app/tsconfig.json +22 -0
- package/templates/app/vercel.json +127 -0
- package/templates/app/vite.config.ts +15 -0
- package/templates/state/context.md +248 -0
- package/templates/state/manifest.json +11 -0
- package/templates/state/plan.md +187 -0
- package/templates/state/project.md +118 -0
- package/templates/state/requirements.md +133 -0
- package/templates/state/roadmap.md +129 -0
- package/templates/state/state.md +131 -0
- package/templates/state/summary.md +273 -0
- package/workflows/add-feature.md +234 -0
- package/workflows/discuss.md +310 -0
- package/workflows/execute-plan.md +222 -0
- package/workflows/execute.md +338 -0
- package/workflows/new-app.md +331 -0
- package/workflows/new-milestone.md +258 -0
- package/workflows/next.md +157 -0
- package/workflows/plan.md +310 -0
- package/workflows/ship.md +296 -0
- package/workflows/status.md +145 -0
|
@@ -0,0 +1,1622 @@
|
|
|
1
|
+
# Frontier SDK Surface Reference
|
|
2
|
+
|
|
3
|
+
Complete API reference for `@frontiertower/frontier-sdk`. Every method, type, and permission extracted from source.
|
|
4
|
+
|
|
5
|
+
Package: `@frontiertower/frontier-sdk`
|
|
6
|
+
Import paths:
|
|
7
|
+
- `@frontiertower/frontier-sdk` -- main SDK class and access modules
|
|
8
|
+
- `@frontiertower/frontier-sdk/ui-utils` -- detection and standalone helpers
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. SDK Initialization
|
|
13
|
+
|
|
14
|
+
### Class: `FrontierSDK`
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import { FrontierSDK } from '@frontiertower/frontier-sdk';
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
#### Constructor
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
const sdk = new FrontierSDK();
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
On construction the SDK:
|
|
27
|
+
1. Instantiates all ten access modules (wallet, storage, chain, user, partnerships, thirdParty, communities, events, offices, navigation).
|
|
28
|
+
2. Registers a `window.addEventListener('message', ...)` listener that routes `SDKResponse` messages from `window.parent`.
|
|
29
|
+
3. Sends an `{ type: 'app:ready', payload: null }` postMessage to `window.parent` to notify the host that the app iframe is ready.
|
|
30
|
+
|
|
31
|
+
#### `destroy(): void`
|
|
32
|
+
|
|
33
|
+
Call when the app is being torn down. Removes the message event listener and clears all pending request promises.
|
|
34
|
+
|
|
35
|
+
#### Internal: `request(type: string, payload?: any): Promise<any>`
|
|
36
|
+
|
|
37
|
+
Used by all access classes. Sends an `SDKRequest` via `window.parent.postMessage` and returns a promise that resolves/rejects when the host responds. Requests time out after **30 000 ms**.
|
|
38
|
+
|
|
39
|
+
### PostMessage Protocol Types
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
interface SDKRequest {
|
|
43
|
+
type: string; // e.g. 'wallet:getBalance'
|
|
44
|
+
requestId: string; // `${Date.now()}-${incrementingId}`
|
|
45
|
+
payload?: any;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface SDKResponse {
|
|
49
|
+
type: 'response' | 'error';
|
|
50
|
+
requestId: string;
|
|
51
|
+
result?: any;
|
|
52
|
+
error?: string;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Module Getters
|
|
57
|
+
|
|
58
|
+
| Getter | Returns | Module |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| `sdk.getWallet()` | `WalletAccess` | Wallet |
|
|
61
|
+
| `sdk.getStorage()` | `StorageAccess` | Storage |
|
|
62
|
+
| `sdk.getChain()` | `ChainAccess` | Chain |
|
|
63
|
+
| `sdk.getUser()` | `UserAccess` | User |
|
|
64
|
+
| `sdk.getPartnerships()` | `PartnershipsAccess` | Partnerships |
|
|
65
|
+
| `sdk.getThirdParty()` | `ThirdPartyAccess` | Third-Party |
|
|
66
|
+
| `sdk.getCommunities()` | `CommunitiesAccess` | Communities |
|
|
67
|
+
| `sdk.getEvents()` | `EventsAccess` | Events |
|
|
68
|
+
| `sdk.getOffices()` | `OfficesAccess` | Offices |
|
|
69
|
+
| `sdk.getNavigation()` | `NavigationAccess` | Navigation |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 2. Wallet Module
|
|
74
|
+
|
|
75
|
+
Access via `sdk.getWallet()`. All methods use the current chain from the chain manager. Write operations require biometric authentication.
|
|
76
|
+
|
|
77
|
+
### Methods
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
getBalance(): Promise<WalletBalance>
|
|
81
|
+
```
|
|
82
|
+
Returns raw balance breakdown (bigint values). Permission: `wallet:getBalance`
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
getBalanceFormatted(): Promise<WalletBalanceFormatted>
|
|
86
|
+
```
|
|
87
|
+
Returns display-formatted balance strings (e.g. `'$10.50'`). Permission: `wallet:getBalanceFormatted`
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
getAddress(): Promise<string>
|
|
91
|
+
```
|
|
92
|
+
Returns the smart account contract address for the current chain. Permission: `wallet:getAddress`
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
getSmartAccount(): Promise<SmartAccount>
|
|
96
|
+
```
|
|
97
|
+
Returns detailed smart account info including deployment status. Permission: `wallet:getSmartAccount`
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
transferERC20(
|
|
101
|
+
tokenAddress: string,
|
|
102
|
+
to: string,
|
|
103
|
+
amount: bigint,
|
|
104
|
+
overrides?: GasOverrides
|
|
105
|
+
): Promise<UserOperationReceipt>
|
|
106
|
+
```
|
|
107
|
+
Transfer ERC20 tokens. Amount in token's smallest unit. Permission: `wallet:transferERC20`
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
approveERC20(
|
|
111
|
+
tokenAddress: string,
|
|
112
|
+
spender: string,
|
|
113
|
+
amount: bigint,
|
|
114
|
+
overrides?: GasOverrides
|
|
115
|
+
): Promise<UserOperationReceipt>
|
|
116
|
+
```
|
|
117
|
+
Approve a spender for ERC20 tokens. Permission: `wallet:approveERC20`
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
transferNative(
|
|
121
|
+
to: string,
|
|
122
|
+
amount: bigint,
|
|
123
|
+
overrides?: GasOverrides
|
|
124
|
+
): Promise<UserOperationReceipt>
|
|
125
|
+
```
|
|
126
|
+
Transfer native currency (ETH). Amount in wei. Permission: `wallet:transferNative`
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
executeCall(
|
|
130
|
+
call: ExecuteCall,
|
|
131
|
+
overrides?: GasOverrides
|
|
132
|
+
): Promise<UserOperationReceipt>
|
|
133
|
+
```
|
|
134
|
+
Execute an arbitrary contract call. Permission: `wallet:executeCall`
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
executeBatchCall(
|
|
138
|
+
calls: ExecuteCall[],
|
|
139
|
+
overrides?: GasOverrides
|
|
140
|
+
): Promise<UserOperationReceipt>
|
|
141
|
+
```
|
|
142
|
+
Execute multiple calls atomically in a single transaction. Permission: `wallet:executeBatchCall`
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
transferFrontierDollar(
|
|
146
|
+
to: string,
|
|
147
|
+
amount: string,
|
|
148
|
+
overrides?: GasOverrides
|
|
149
|
+
): Promise<UserOperationReceipt>
|
|
150
|
+
```
|
|
151
|
+
Transfer FND (Frontier Network Dollar). Amount is human-readable string (e.g. `'10.5'`). Permission: `wallet:transferFrontierDollar`
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
transferInternalFrontierDollar(
|
|
155
|
+
to: string,
|
|
156
|
+
amount: string,
|
|
157
|
+
overrides?: GasOverrides
|
|
158
|
+
): Promise<UserOperationReceipt>
|
|
159
|
+
```
|
|
160
|
+
Transfer iFND (Internal Frontier Network Dollar). Amount is human-readable string. Permission: `wallet:transferInternalFrontierDollar`
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
transferOverallFrontierDollar(
|
|
164
|
+
to: string,
|
|
165
|
+
amount: string,
|
|
166
|
+
overrides?: GasOverrides
|
|
167
|
+
): Promise<UserOperationReceipt>
|
|
168
|
+
```
|
|
169
|
+
Transfer using iFND first, falling back to FND for the remainder. Permission: `wallet:transferOverallFrontierDollar`
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
payWithFrontierDollar(
|
|
173
|
+
to: string,
|
|
174
|
+
amount: string,
|
|
175
|
+
paymentId: string
|
|
176
|
+
): Promise<UserOperationReceipt>
|
|
177
|
+
```
|
|
178
|
+
Pay via PaymentRouter with a UUID payment reference. Uses iFND with priority, falling back to FND. Supports multi-token split in a single transaction. Permission: `wallet:payWithFrontierDollar`
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
getSupportedTokens(): Promise<string[]>
|
|
182
|
+
```
|
|
183
|
+
Returns token symbols supported for swaps on the current chain (e.g. `['FND', 'USDC', 'WETH']`). Permission: `wallet:getSupportedTokens`
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
swap(
|
|
187
|
+
sourceToken: string,
|
|
188
|
+
targetToken: string,
|
|
189
|
+
sourceNetwork: string,
|
|
190
|
+
targetNetwork: string,
|
|
191
|
+
amount: string
|
|
192
|
+
): Promise<SwapResult>
|
|
193
|
+
```
|
|
194
|
+
Execute a token swap (same-chain or cross-chain). Amount is human-readable. Permission: `wallet:swap`
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
quoteSwap(
|
|
198
|
+
sourceToken: string,
|
|
199
|
+
targetToken: string,
|
|
200
|
+
sourceNetwork: string,
|
|
201
|
+
targetNetwork: string,
|
|
202
|
+
amount: string
|
|
203
|
+
): Promise<SwapQuote>
|
|
204
|
+
```
|
|
205
|
+
Get a swap quote without executing. Permission: `wallet:quoteSwap`
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
getUsdDepositInstructions(): Promise<OnRampResponse<UsdDepositInstructions>>
|
|
209
|
+
```
|
|
210
|
+
Get US bank details for fiat-to-crypto on-ramp. Requires approved KYC. Permission: `wallet:getUsdDepositInstructions`
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
getEurDepositInstructions(): Promise<OnRampResponse<EurDepositInstructions>>
|
|
214
|
+
```
|
|
215
|
+
Get SEPA bank details for EUR fiat-to-crypto on-ramp. Requires approved KYC. Permission: `wallet:getEurDepositInstructions`
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
getLinkedBanks(): Promise<LinkedBanksResponse>
|
|
219
|
+
```
|
|
220
|
+
Get all linked bank accounts for off-ramp withdrawals. Requires approved KYC. Permission: `wallet:getLinkedBanks`
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
linkUsBankAccount(
|
|
224
|
+
accountOwnerName: string,
|
|
225
|
+
bankName: string,
|
|
226
|
+
routingNumber: string,
|
|
227
|
+
accountNumber: string,
|
|
228
|
+
checkingOrSavings: 'checking' | 'savings',
|
|
229
|
+
address: BillingAddress
|
|
230
|
+
): Promise<LinkBankResponse>
|
|
231
|
+
```
|
|
232
|
+
Link a US bank account for USD withdrawals via ACH. Requires approved KYC. Permission: `wallet:linkUsBankAccount`
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
linkEuroAccount(
|
|
236
|
+
accountOwnerName: string,
|
|
237
|
+
accountOwnerType: AccountOwnerType,
|
|
238
|
+
firstName: string,
|
|
239
|
+
lastName: string,
|
|
240
|
+
ibanAccountNumber: string,
|
|
241
|
+
bic?: string
|
|
242
|
+
): Promise<LinkBankResponse>
|
|
243
|
+
```
|
|
244
|
+
Link a EUR/IBAN bank account for SEPA withdrawals. Requires approved KYC. Permission: `wallet:linkEuroAccount`
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
deleteLinkedBank(bankId: string): Promise<void>
|
|
248
|
+
```
|
|
249
|
+
Delete a linked bank account. Permission: `wallet:deleteLinkedBank`
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
getDeprecatedSmartAccounts(): Promise<DeprecatedSmartAccount[]>
|
|
253
|
+
```
|
|
254
|
+
Get deprecated smart accounts that still have active gas sponsorship. Permission: `wallet:getDeprecatedSmartAccounts`
|
|
255
|
+
|
|
256
|
+
### Wallet Types
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
interface SmartAccount {
|
|
260
|
+
id: number;
|
|
261
|
+
ownerAddress: string;
|
|
262
|
+
contractAddress: string | null;
|
|
263
|
+
network: string;
|
|
264
|
+
status: string;
|
|
265
|
+
deploymentTransactionHash: string;
|
|
266
|
+
createdAt: string;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
interface WalletBalance {
|
|
270
|
+
total: bigint;
|
|
271
|
+
fnd: bigint;
|
|
272
|
+
internalFnd: bigint;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
interface WalletBalanceFormatted {
|
|
276
|
+
total: string; // e.g. '$10.50'
|
|
277
|
+
fnd: string;
|
|
278
|
+
internalFnd: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
interface UserOperationReceipt {
|
|
282
|
+
userOpHash: string;
|
|
283
|
+
transactionHash: string;
|
|
284
|
+
blockNumber: bigint;
|
|
285
|
+
success: boolean;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
interface GasOverrides {
|
|
289
|
+
maxFeePerGas?: bigint;
|
|
290
|
+
maxPriorityFeePerGas?: bigint;
|
|
291
|
+
gasLimit?: bigint;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
interface ExecuteCall {
|
|
295
|
+
target: string;
|
|
296
|
+
value?: bigint;
|
|
297
|
+
data: string;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
interface SwapParams {
|
|
301
|
+
sourceToken: string;
|
|
302
|
+
targetToken: string;
|
|
303
|
+
sourceNetwork: string;
|
|
304
|
+
targetNetwork: string;
|
|
305
|
+
amount: string;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
enum SwapResultStatus {
|
|
309
|
+
COMPLETED = 'COMPLETED',
|
|
310
|
+
SUBMITTED = 'SUBMITTED',
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
interface SwapResult {
|
|
314
|
+
sourceChain: object;
|
|
315
|
+
targetChain: object;
|
|
316
|
+
sourceToken: object;
|
|
317
|
+
targetToken: object;
|
|
318
|
+
status: SwapResultStatus;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
interface SwapQuote {
|
|
322
|
+
sourceChain: object;
|
|
323
|
+
targetChain: object;
|
|
324
|
+
sourceToken: object;
|
|
325
|
+
targetToken: object;
|
|
326
|
+
expectedAmountOut: string;
|
|
327
|
+
minAmountOut: string;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
interface UsdDepositInstructions {
|
|
331
|
+
currency: 'usd';
|
|
332
|
+
bankName: string;
|
|
333
|
+
bankAddress: string;
|
|
334
|
+
bankRoutingNumber: string;
|
|
335
|
+
bankAccountNumber: string;
|
|
336
|
+
bankBeneficiaryName: string;
|
|
337
|
+
paymentRail: string;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
interface EurDepositInstructions {
|
|
341
|
+
currency: 'eur';
|
|
342
|
+
iban: string;
|
|
343
|
+
bic: string;
|
|
344
|
+
accountHolderName: string;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
interface OnRampResponse<T = UsdDepositInstructions | EurDepositInstructions> {
|
|
348
|
+
currency: 'usd' | 'eur';
|
|
349
|
+
depositInstructions: T;
|
|
350
|
+
destinationAddress: string;
|
|
351
|
+
destinationNetwork: string;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
interface LinkedBank {
|
|
355
|
+
id: string;
|
|
356
|
+
bankName: string;
|
|
357
|
+
last4: string;
|
|
358
|
+
withdrawalAddress: string;
|
|
359
|
+
network: string;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
interface LinkedBanksResponse {
|
|
363
|
+
banks: LinkedBank[];
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
interface LinkBankResponse {
|
|
367
|
+
externalAccountId: string;
|
|
368
|
+
bankName: string;
|
|
369
|
+
withdrawalAddress: string;
|
|
370
|
+
network: string;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
interface BillingAddress {
|
|
374
|
+
streetLine1: string;
|
|
375
|
+
streetLine2?: string;
|
|
376
|
+
city: string;
|
|
377
|
+
state: string;
|
|
378
|
+
postalCode: string;
|
|
379
|
+
country: string;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
type AccountOwnerType = 'individual' | 'business';
|
|
383
|
+
|
|
384
|
+
interface DeprecatedSmartAccount {
|
|
385
|
+
id: number;
|
|
386
|
+
ownerAddress: string;
|
|
387
|
+
contractAddress: string;
|
|
388
|
+
network: string;
|
|
389
|
+
deprecatedAt: string;
|
|
390
|
+
version: number;
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## 3. Storage Module
|
|
397
|
+
|
|
398
|
+
Access via `sdk.getStorage()`. Provides persistent key-value storage scoped to the app.
|
|
399
|
+
|
|
400
|
+
### Methods
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
get<T = any>(key: string): Promise<T>
|
|
404
|
+
```
|
|
405
|
+
Read a value by key. Permission: `storage:get`
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
set(key: string, value: any): Promise<void>
|
|
409
|
+
```
|
|
410
|
+
Write a value by key. Permission: `storage:set`
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
remove(key: string): Promise<void>
|
|
414
|
+
```
|
|
415
|
+
Delete a key. Permission: `storage:remove`
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
clear(): Promise<void>
|
|
419
|
+
```
|
|
420
|
+
Delete all keys. Permission: `storage:clear`
|
|
421
|
+
|
|
422
|
+
### Storage Types
|
|
423
|
+
|
|
424
|
+
No additional types -- uses generic `T` for get, `any` for set.
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## 4. Chain Module
|
|
429
|
+
|
|
430
|
+
Access via `sdk.getChain()`. Query and switch blockchain networks.
|
|
431
|
+
|
|
432
|
+
### Methods
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
getCurrentNetwork(): Promise<string>
|
|
436
|
+
```
|
|
437
|
+
Returns the current network identifier (e.g. `'base'`, `'base-sepolia'`). Permission: `chain:getCurrentNetwork`
|
|
438
|
+
|
|
439
|
+
```typescript
|
|
440
|
+
getAvailableNetworks(): Promise<string[]>
|
|
441
|
+
```
|
|
442
|
+
Returns all network identifiers the app can switch to. Permission: `chain:getAvailableNetworks`
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
switchNetwork(network: string): Promise<void>
|
|
446
|
+
```
|
|
447
|
+
Switch active blockchain network. Affects all subsequent wallet operations. Permission: `chain:switchNetwork`
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
getCurrentChainConfig(): Promise<ChainConfig>
|
|
451
|
+
```
|
|
452
|
+
Returns full chain configuration for the current network. Permission: `chain:getCurrentChainConfig`
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
getContractAddresses(): Promise<{
|
|
456
|
+
fnd: string;
|
|
457
|
+
iFnd: string | null;
|
|
458
|
+
paymentRouter: string;
|
|
459
|
+
subscriptionManager: string;
|
|
460
|
+
}>
|
|
461
|
+
```
|
|
462
|
+
Returns addresses for FND, iFND (may be null), PaymentRouter, and SubscriptionManager contracts on the current chain. Permission: `chain:getContractAddresses`
|
|
463
|
+
|
|
464
|
+
### Chain Types
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
enum Underlying {
|
|
468
|
+
USD = "USD",
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
interface Token {
|
|
472
|
+
name: string;
|
|
473
|
+
symbol: string;
|
|
474
|
+
decimals: number;
|
|
475
|
+
address: string;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
interface StableCoin extends Token {
|
|
479
|
+
underlying: Underlying;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
interface ChainConfig {
|
|
483
|
+
id: number;
|
|
484
|
+
name: string;
|
|
485
|
+
network: string;
|
|
486
|
+
bridgeSwapRouterFactoryAddress: string;
|
|
487
|
+
uniswapV3FactoryAddress: string;
|
|
488
|
+
nativeCurrency: {
|
|
489
|
+
name: string;
|
|
490
|
+
symbol: string;
|
|
491
|
+
decimals: number;
|
|
492
|
+
};
|
|
493
|
+
blockExplorer: {
|
|
494
|
+
name: string;
|
|
495
|
+
url: string;
|
|
496
|
+
};
|
|
497
|
+
stableCoins: StableCoin[];
|
|
498
|
+
supportedTokens: Token[];
|
|
499
|
+
testnet: boolean;
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
## 5. User Module
|
|
506
|
+
|
|
507
|
+
Access via `sdk.getUser()`. Query user info, profiles, referrals, KYC, and access controls.
|
|
508
|
+
|
|
509
|
+
### Methods
|
|
510
|
+
|
|
511
|
+
```typescript
|
|
512
|
+
getDetails(): Promise<User>
|
|
513
|
+
```
|
|
514
|
+
Returns basic user info (id, email, name, active/superuser status). Permission: `user:getDetails`
|
|
515
|
+
|
|
516
|
+
```typescript
|
|
517
|
+
getProfile(): Promise<UserProfile>
|
|
518
|
+
```
|
|
519
|
+
Returns detailed profile (social handles, preferences, community, notification settings). Permission: `user:getProfile`
|
|
520
|
+
|
|
521
|
+
```typescript
|
|
522
|
+
getReferralOverview(): Promise<ReferralOverview>
|
|
523
|
+
```
|
|
524
|
+
Returns referral statistics (count, ranking, referral link/code). Permission: `user:getReferralOverview`
|
|
525
|
+
|
|
526
|
+
```typescript
|
|
527
|
+
getReferralDetails(page?: number): Promise<PaginatedResponse<ReferralDetails>>
|
|
528
|
+
```
|
|
529
|
+
Returns paginated referral details. Permission: `user:getReferralDetails`
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
addUserContact(data: UserContactPayload): Promise<void>
|
|
533
|
+
```
|
|
534
|
+
Submit contact information for the current user. Permission: `user:addUserContact`
|
|
535
|
+
|
|
536
|
+
```typescript
|
|
537
|
+
getOrCreateKyc(redirectUri?: string): Promise<KycStatusResponse>
|
|
538
|
+
```
|
|
539
|
+
Get or initiate KYC verification. Returns status and a KYC link if verification has been started. Permission: `user:getOrCreateKyc`
|
|
540
|
+
|
|
541
|
+
```typescript
|
|
542
|
+
createSignupRequest(payload: CreateSignupRequestPayload): Promise<CreateSignupRequestResponse>
|
|
543
|
+
```
|
|
544
|
+
Submit a new membership signup request with crypto payment. Permission: `user:createSignupRequest`
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
getVerifiedAccessControls(): Promise<AccessControlsPayload>
|
|
548
|
+
```
|
|
549
|
+
Returns cryptographically verified access controls signed by the Frontier API server. The SDK verifies an ECDSA secp256k1 signature against hardcoded per-environment public keys inside the iframe. **Use this for all access-gating decisions** -- unsigned data from other SDK methods should not be trusted for feature gating. Throws if signature verification fails. Permission: `user:getVerifiedAccessControls`
|
|
550
|
+
|
|
551
|
+
### User Types
|
|
552
|
+
|
|
553
|
+
```typescript
|
|
554
|
+
interface User {
|
|
555
|
+
id: number;
|
|
556
|
+
email: string;
|
|
557
|
+
firstName: string;
|
|
558
|
+
lastName: string;
|
|
559
|
+
isActive: boolean;
|
|
560
|
+
dateJoined: string;
|
|
561
|
+
isSuperuser: boolean;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
interface UserProfile {
|
|
565
|
+
id: number;
|
|
566
|
+
user: number;
|
|
567
|
+
firstName: string;
|
|
568
|
+
lastName: string;
|
|
569
|
+
nickname: string;
|
|
570
|
+
profilePicture: string;
|
|
571
|
+
phoneNumber: string;
|
|
572
|
+
community: string;
|
|
573
|
+
communityName: string;
|
|
574
|
+
organization: string;
|
|
575
|
+
organizationRole: string;
|
|
576
|
+
socialSite: string;
|
|
577
|
+
socialHandle: string;
|
|
578
|
+
githubHandle: string;
|
|
579
|
+
currentWork: string;
|
|
580
|
+
notableWork: string;
|
|
581
|
+
receiveUpdates: boolean;
|
|
582
|
+
notificationCommunityEvent: boolean;
|
|
583
|
+
notificationTowerEvent: boolean;
|
|
584
|
+
notificationUpcomingEvent: boolean;
|
|
585
|
+
notificationTweetPicked: boolean;
|
|
586
|
+
notifyEventInvites: boolean;
|
|
587
|
+
optInSms: boolean;
|
|
588
|
+
howDidYouHearAboutUs: string;
|
|
589
|
+
braggingStatement: string;
|
|
590
|
+
contributionStatement: string;
|
|
591
|
+
hasUsablePassword: string;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
interface PaginatedResponse<T> {
|
|
595
|
+
count: number;
|
|
596
|
+
results: T[];
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
interface ReferralOverview {
|
|
600
|
+
referralCount: number;
|
|
601
|
+
ranking: number;
|
|
602
|
+
referralLink: string;
|
|
603
|
+
referralCode: string;
|
|
604
|
+
referredBy: string | null;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
interface ReferralDetails {
|
|
608
|
+
name: string;
|
|
609
|
+
email: string;
|
|
610
|
+
referralDate: string;
|
|
611
|
+
reward: string;
|
|
612
|
+
status: string;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
interface UserContact {
|
|
616
|
+
email: string;
|
|
617
|
+
phone: string;
|
|
618
|
+
name: string;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
interface UserContactPayload {
|
|
622
|
+
contacts: UserContact[];
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
type KycStatus = 'not_started' | 'pending' | 'in_review' | 'approved' | 'rejected';
|
|
626
|
+
type TosStatus = 'pending' | 'approved';
|
|
627
|
+
|
|
628
|
+
interface KycStatusResponse {
|
|
629
|
+
status: KycStatus;
|
|
630
|
+
isApproved: boolean;
|
|
631
|
+
rejectionReason: string | null;
|
|
632
|
+
kycLinkId: string | null;
|
|
633
|
+
kycLink: string | null;
|
|
634
|
+
tosStatus: TosStatus | null;
|
|
635
|
+
tosLink: string | null;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
interface CreateSignupRequestPayload {
|
|
639
|
+
subscriptionPlan: string;
|
|
640
|
+
subscriptionInterval: string;
|
|
641
|
+
firstName: string;
|
|
642
|
+
lastName: string;
|
|
643
|
+
email: string;
|
|
644
|
+
phoneNumber: string;
|
|
645
|
+
socialSite: string;
|
|
646
|
+
socialHandle: string;
|
|
647
|
+
currentWork: string;
|
|
648
|
+
howDidYouHearAboutUs: string;
|
|
649
|
+
braggingStatement: string;
|
|
650
|
+
contributionStatement: string;
|
|
651
|
+
billingFirstName: string;
|
|
652
|
+
billingLastName: string;
|
|
653
|
+
billingEmail: string;
|
|
654
|
+
billingPhoneNumber: string;
|
|
655
|
+
paymentProvider: 'crypto';
|
|
656
|
+
smartAccount: number;
|
|
657
|
+
community: string;
|
|
658
|
+
githubHandle?: string;
|
|
659
|
+
notableWork?: string;
|
|
660
|
+
referralCode?: string;
|
|
661
|
+
receiveUpdates?: boolean;
|
|
662
|
+
optInSms?: boolean;
|
|
663
|
+
organization?: string;
|
|
664
|
+
organizationRole?: string;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
interface CreateSignupRequestResponse {
|
|
668
|
+
subscriptionUuid: string;
|
|
669
|
+
paymentProvider: string;
|
|
670
|
+
}
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
### Access Controls Types
|
|
674
|
+
|
|
675
|
+
```typescript
|
|
676
|
+
interface AccessControlsPayload {
|
|
677
|
+
smartAccountAddress: string | null;
|
|
678
|
+
email: string;
|
|
679
|
+
isSuperuser: boolean;
|
|
680
|
+
subscriptionStatus: string | null; // 'active' | 'canceled' | 'awaiting_approval' | null
|
|
681
|
+
subscriptionPlan: string | null;
|
|
682
|
+
subscriptionInterval: string | null;
|
|
683
|
+
subscriptionType: string | null; // 'crypto' | 'stripe' | 'grant' | 'office' | 'internship' | null
|
|
684
|
+
addOns: string[];
|
|
685
|
+
communities: string[];
|
|
686
|
+
managedCommunities: string[];
|
|
687
|
+
timestamp: string;
|
|
688
|
+
kid: string;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
interface SignedAccessControls {
|
|
692
|
+
accessControls: string; // Base64-encoded canonical JSON payload
|
|
693
|
+
stage: string; // API stage (e.g. 'production', 'sandbox')
|
|
694
|
+
signature: string; // Hex-encoded ECDSA signature (r||s, 128 hex chars)
|
|
695
|
+
}
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
---
|
|
699
|
+
|
|
700
|
+
## 6. Partnerships Module
|
|
701
|
+
|
|
702
|
+
Access via `sdk.getPartnerships()`. Manage sponsors and sponsor passes.
|
|
703
|
+
|
|
704
|
+
### Methods
|
|
705
|
+
|
|
706
|
+
```typescript
|
|
707
|
+
createSponsorPass(payload: CreateSponsorPassRequest): Promise<SponsorPass>
|
|
708
|
+
```
|
|
709
|
+
Create a new SponsorPass. Permission: `partnerships:createSponsorPass`
|
|
710
|
+
|
|
711
|
+
```typescript
|
|
712
|
+
listActiveSponsorPasses(payload?: ListSponsorPassesParams): Promise<PaginatedResponse<SponsorPass>>
|
|
713
|
+
```
|
|
714
|
+
List active (non-revoked) SponsorPasses, paginated. Permission: `partnerships:listActiveSponsorPasses`
|
|
715
|
+
|
|
716
|
+
```typescript
|
|
717
|
+
listAllSponsorPasses(payload?: ListAllSponsorPassesParams): Promise<PaginatedResponse<SponsorPass>>
|
|
718
|
+
```
|
|
719
|
+
List all SponsorPasses, optionally including revoked. Permission: `partnerships:listAllSponsorPasses`
|
|
720
|
+
|
|
721
|
+
```typescript
|
|
722
|
+
listSponsors(payload?: ListSponsorsParams): Promise<PaginatedResponse<Sponsor>>
|
|
723
|
+
```
|
|
724
|
+
List sponsors the user manages, paginated. Permission: `partnerships:listSponsors`
|
|
725
|
+
|
|
726
|
+
```typescript
|
|
727
|
+
getSponsor(payload: { id: number }): Promise<Sponsor>
|
|
728
|
+
```
|
|
729
|
+
Retrieve a Sponsor by ID. Permission: `partnerships:getSponsor`
|
|
730
|
+
|
|
731
|
+
```typescript
|
|
732
|
+
getSponsorPass(payload: { id: number }): Promise<SponsorPass>
|
|
733
|
+
```
|
|
734
|
+
Retrieve a SponsorPass by ID. Permission: `partnerships:getSponsorPass`
|
|
735
|
+
|
|
736
|
+
```typescript
|
|
737
|
+
revokeSponsorPass(payload: { id: number }): Promise<void>
|
|
738
|
+
```
|
|
739
|
+
Revoke (not delete) a SponsorPass. Permission: `partnerships:revokeSponsorPass`
|
|
740
|
+
|
|
741
|
+
### Partnerships Types
|
|
742
|
+
|
|
743
|
+
```typescript
|
|
744
|
+
type SponsorPassStatus = 'active' | 'revoked';
|
|
745
|
+
|
|
746
|
+
interface SponsorPass {
|
|
747
|
+
id: number;
|
|
748
|
+
sponsor: number;
|
|
749
|
+
sponsorName: string;
|
|
750
|
+
firstName: string;
|
|
751
|
+
lastName: string;
|
|
752
|
+
email: string;
|
|
753
|
+
status: SponsorPassStatus;
|
|
754
|
+
expiresAt: string | null;
|
|
755
|
+
createdAt: string;
|
|
756
|
+
updatedAt: string;
|
|
757
|
+
revokedAt: string | null;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
interface CreateSponsorPassRequest {
|
|
761
|
+
sponsor: number;
|
|
762
|
+
firstName: string;
|
|
763
|
+
lastName: string;
|
|
764
|
+
email: string;
|
|
765
|
+
expiresAt?: string;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
interface ListSponsorPassesParams {
|
|
769
|
+
limit?: number;
|
|
770
|
+
offset?: number;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
interface ListAllSponsorPassesParams extends ListSponsorPassesParams {
|
|
774
|
+
includeRevoked?: boolean;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
interface Sponsor {
|
|
778
|
+
id: number;
|
|
779
|
+
name: string;
|
|
780
|
+
dailyRate: string;
|
|
781
|
+
notes: string;
|
|
782
|
+
createdAt: string;
|
|
783
|
+
updatedAt: string;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
interface ListSponsorsParams {
|
|
787
|
+
limit?: number;
|
|
788
|
+
offset?: number;
|
|
789
|
+
}
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
---
|
|
793
|
+
|
|
794
|
+
## 7. Third-Party Module
|
|
795
|
+
|
|
796
|
+
Access via `sdk.getThirdParty()`. Manage developer accounts, registered apps, and webhooks.
|
|
797
|
+
|
|
798
|
+
### Developer Methods
|
|
799
|
+
|
|
800
|
+
```typescript
|
|
801
|
+
listDevelopers(payload?: ListParams): Promise<PaginatedResponse<Developer>>
|
|
802
|
+
```
|
|
803
|
+
List developer accounts, paginated. Permission: `thirdParty:listDevelopers`
|
|
804
|
+
|
|
805
|
+
```typescript
|
|
806
|
+
getDeveloper(payload: { id: number }): Promise<Developer>
|
|
807
|
+
```
|
|
808
|
+
Get developer details by ID. Permission: `thirdParty:getDeveloper`
|
|
809
|
+
|
|
810
|
+
```typescript
|
|
811
|
+
updateDeveloper(payload: { id: number; data: UpdateDeveloperRequest }): Promise<Developer>
|
|
812
|
+
```
|
|
813
|
+
Update developer information. Permission: `thirdParty:updateDeveloper`
|
|
814
|
+
|
|
815
|
+
```typescript
|
|
816
|
+
rotateDeveloperApiKey(payload: { id: number }): Promise<RotateKeyResponse>
|
|
817
|
+
```
|
|
818
|
+
Rotate developer API key. New key is only shown once in the response. Permission: `thirdParty:rotateDeveloperApiKey`
|
|
819
|
+
|
|
820
|
+
### App Methods
|
|
821
|
+
|
|
822
|
+
```typescript
|
|
823
|
+
listApps(payload?: ListAppsParams): Promise<PaginatedResponse<App>>
|
|
824
|
+
```
|
|
825
|
+
List registered apps, paginated. Optional `developerId` filter. Permission: `thirdParty:listApps`
|
|
826
|
+
|
|
827
|
+
```typescript
|
|
828
|
+
createApp(payload: CreateAppRequest): Promise<App>
|
|
829
|
+
```
|
|
830
|
+
Register a new app. Name, description, and icon are auto-fetched from URL metadata. Permission: `thirdParty:createApp`
|
|
831
|
+
|
|
832
|
+
```typescript
|
|
833
|
+
getApp(payload: { id: number }): Promise<App>
|
|
834
|
+
```
|
|
835
|
+
Get app details by ID. Permission: `thirdParty:getApp`
|
|
836
|
+
|
|
837
|
+
```typescript
|
|
838
|
+
updateApp(payload: { id: number; data: UpdateAppRequest }): Promise<App>
|
|
839
|
+
```
|
|
840
|
+
Update an app. Permission: `thirdParty:updateApp`
|
|
841
|
+
|
|
842
|
+
```typescript
|
|
843
|
+
deleteApp(payload: { id: number }): Promise<void>
|
|
844
|
+
```
|
|
845
|
+
Request app deactivation. Permission: `thirdParty:deleteApp`
|
|
846
|
+
|
|
847
|
+
### Webhook Methods
|
|
848
|
+
|
|
849
|
+
```typescript
|
|
850
|
+
listWebhooks(payload?: ListWebhooksParams): Promise<PaginatedResponse<Webhook>>
|
|
851
|
+
```
|
|
852
|
+
List webhooks, paginated. Max 3 webhooks per developer. Optional `developerId` filter. Permission: `thirdParty:listWebhooks`
|
|
853
|
+
|
|
854
|
+
```typescript
|
|
855
|
+
createWebhook(payload: CreateWebhookRequest): Promise<Webhook>
|
|
856
|
+
```
|
|
857
|
+
Create a new webhook. Requires admin approval before going live. Permission: `thirdParty:createWebhook`
|
|
858
|
+
|
|
859
|
+
```typescript
|
|
860
|
+
getWebhook(payload: { id: number }): Promise<Webhook>
|
|
861
|
+
```
|
|
862
|
+
Get webhook details by ID. Permission: `thirdParty:getWebhook`
|
|
863
|
+
|
|
864
|
+
```typescript
|
|
865
|
+
updateWebhook(payload: { id: number; data: UpdateWebhookRequest }): Promise<Webhook>
|
|
866
|
+
```
|
|
867
|
+
Update a webhook. Config changes require admin re-approval. Permission: `thirdParty:updateWebhook`
|
|
868
|
+
|
|
869
|
+
```typescript
|
|
870
|
+
deleteWebhook(payload: { id: number }): Promise<void>
|
|
871
|
+
```
|
|
872
|
+
Delete a webhook. Permission: `thirdParty:deleteWebhook`
|
|
873
|
+
|
|
874
|
+
```typescript
|
|
875
|
+
rotateWebhookSigningKey(payload: { id: number }): Promise<RotateWebhookKeyResponse>
|
|
876
|
+
```
|
|
877
|
+
Rotate webhook signing key. New public key returned in response. Permission: `thirdParty:rotateWebhookSigningKey`
|
|
878
|
+
|
|
879
|
+
### Third-Party Types
|
|
880
|
+
|
|
881
|
+
```typescript
|
|
882
|
+
interface Developer {
|
|
883
|
+
id: number;
|
|
884
|
+
name: string;
|
|
885
|
+
description: string;
|
|
886
|
+
email: string;
|
|
887
|
+
apiKey: string;
|
|
888
|
+
createdAt: string;
|
|
889
|
+
updatedAt: string;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
interface UpdateDeveloperRequest {
|
|
893
|
+
name?: string;
|
|
894
|
+
description?: string;
|
|
895
|
+
email?: string;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
interface RotateKeyResponse {
|
|
899
|
+
message: string;
|
|
900
|
+
developer: Developer;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
type AppStatus =
|
|
904
|
+
| 'in_review'
|
|
905
|
+
| 'accepted'
|
|
906
|
+
| 'released'
|
|
907
|
+
| 'rejected'
|
|
908
|
+
| 'request_deactivation'
|
|
909
|
+
| 'deactivated';
|
|
910
|
+
|
|
911
|
+
type AppPermission = string;
|
|
912
|
+
|
|
913
|
+
interface App {
|
|
914
|
+
id: number;
|
|
915
|
+
developer: number;
|
|
916
|
+
icon: string | null;
|
|
917
|
+
name: string;
|
|
918
|
+
readableId: string;
|
|
919
|
+
description: string;
|
|
920
|
+
url: string;
|
|
921
|
+
cnameEntry: string;
|
|
922
|
+
txtEntry: string | null;
|
|
923
|
+
permissions: AppPermission[];
|
|
924
|
+
permissionDisclaimer: string;
|
|
925
|
+
status: AppStatus;
|
|
926
|
+
reviewNotes: string;
|
|
927
|
+
createdAt: string;
|
|
928
|
+
updatedAt: string;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
interface CreateAppRequest {
|
|
932
|
+
developer: number;
|
|
933
|
+
url: string;
|
|
934
|
+
cnameEntry: string;
|
|
935
|
+
txtEntry?: string;
|
|
936
|
+
permissions: AppPermission[];
|
|
937
|
+
permissionDisclaimer: string;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
interface UpdateAppRequest {
|
|
941
|
+
developer?: number;
|
|
942
|
+
url?: string;
|
|
943
|
+
cnameEntry?: string;
|
|
944
|
+
txtEntry?: string;
|
|
945
|
+
permissions?: AppPermission[];
|
|
946
|
+
permissionDisclaimer?: string;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
type WebhookStatus = 'IN_REVIEW' | 'LIVE' | 'REJECTED';
|
|
950
|
+
type WebhookEvent = string;
|
|
951
|
+
type WebhookScope = Record<string, number[] | '*'>;
|
|
952
|
+
|
|
953
|
+
interface WebhookConfig {
|
|
954
|
+
events: WebhookEvent[];
|
|
955
|
+
scope: WebhookScope;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
interface Webhook {
|
|
959
|
+
id: number;
|
|
960
|
+
developer: number;
|
|
961
|
+
name: string;
|
|
962
|
+
description: string;
|
|
963
|
+
targetUrl: string;
|
|
964
|
+
config: WebhookConfig;
|
|
965
|
+
signingPublicKey: string;
|
|
966
|
+
status: WebhookStatus;
|
|
967
|
+
reviewNotes: string;
|
|
968
|
+
createdAt: string;
|
|
969
|
+
updatedAt: string;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
interface CreateWebhookRequest {
|
|
973
|
+
developer: number;
|
|
974
|
+
name: string;
|
|
975
|
+
description: string;
|
|
976
|
+
targetUrl: string;
|
|
977
|
+
config: WebhookConfig;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
interface UpdateWebhookRequest {
|
|
981
|
+
developer?: number;
|
|
982
|
+
name?: string;
|
|
983
|
+
description?: string;
|
|
984
|
+
targetUrl?: string;
|
|
985
|
+
config?: WebhookConfig;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
interface RotateWebhookKeyResponse {
|
|
989
|
+
message: string;
|
|
990
|
+
webhook: Webhook;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
interface ListParams {
|
|
994
|
+
limit?: number;
|
|
995
|
+
offset?: number;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
interface ListAppsParams extends ListParams {
|
|
999
|
+
developerId?: number;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
interface ListWebhooksParams extends ListParams {
|
|
1003
|
+
developerId?: number;
|
|
1004
|
+
}
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
---
|
|
1008
|
+
|
|
1009
|
+
## 8. Communities Module
|
|
1010
|
+
|
|
1011
|
+
Access via `sdk.getCommunities()`. Manage communities, internship passes, and member reassignment requests.
|
|
1012
|
+
|
|
1013
|
+
Community listing is public. Internship passes require authentication, an active subscription, and community manager status. Reassign requests require authentication; creating requires managing the member's current community, accepting requires managing the target community. Superusers can access everything.
|
|
1014
|
+
|
|
1015
|
+
### Methods
|
|
1016
|
+
|
|
1017
|
+
```typescript
|
|
1018
|
+
listCommunities(payload?: ListCommunitiesParams): Promise<PaginatedResponse<Community>>
|
|
1019
|
+
```
|
|
1020
|
+
List all visible communities, paginated. Permission: `communities:listCommunities`
|
|
1021
|
+
|
|
1022
|
+
```typescript
|
|
1023
|
+
getCommunity(payload: { idOrSlug: string | number }): Promise<Community>
|
|
1024
|
+
```
|
|
1025
|
+
Get a community by numeric ID or slug string. Permission: `communities:getCommunity`
|
|
1026
|
+
|
|
1027
|
+
```typescript
|
|
1028
|
+
createInternshipPass(payload: CreateInternshipPassRequest): Promise<InternshipPass>
|
|
1029
|
+
```
|
|
1030
|
+
Create an internship pass. Auto-creates an inactive account if the user does not exist. Permission: `communities:createInternshipPass`
|
|
1031
|
+
|
|
1032
|
+
```typescript
|
|
1033
|
+
listInternshipPasses(payload?: ListInternshipPassesParams): Promise<PaginatedResponse<InternshipPass>>
|
|
1034
|
+
```
|
|
1035
|
+
List internship passes for managed communities. Active only by default; set `includeRevoked: true` to include revoked. Permission: `communities:listInternshipPasses`
|
|
1036
|
+
|
|
1037
|
+
```typescript
|
|
1038
|
+
getInternshipPass(payload: { id: number }): Promise<InternshipPass>
|
|
1039
|
+
```
|
|
1040
|
+
Get an internship pass by ID. Permission: `communities:getInternshipPass`
|
|
1041
|
+
|
|
1042
|
+
```typescript
|
|
1043
|
+
revokeInternshipPass(payload: { id: number }): Promise<void>
|
|
1044
|
+
```
|
|
1045
|
+
Revoke an internship pass. Cannot revoke an already-revoked pass. Permission: `communities:revokeInternshipPass`
|
|
1046
|
+
|
|
1047
|
+
```typescript
|
|
1048
|
+
createReassignRequest(payload: CreateReassignRequestPayload): Promise<ReassignRequest>
|
|
1049
|
+
```
|
|
1050
|
+
Request to move a member to a different community. Caller must manage the member's current community. Permission: `communities:createReassignRequest`
|
|
1051
|
+
|
|
1052
|
+
```typescript
|
|
1053
|
+
listReassignRequests(payload?: ListReassignRequestsParams): Promise<PaginatedResponse<ReassignRequest>>
|
|
1054
|
+
```
|
|
1055
|
+
List pending reassign requests visible to the caller. Permission: `communities:listReassignRequests`
|
|
1056
|
+
|
|
1057
|
+
```typescript
|
|
1058
|
+
getReassignRequest(payload: { id: number }): Promise<ReassignRequest>
|
|
1059
|
+
```
|
|
1060
|
+
Get a reassign request by ID. Permission: `communities:getReassignRequest`
|
|
1061
|
+
|
|
1062
|
+
```typescript
|
|
1063
|
+
acceptReassignRequest(payload: { id: number }): Promise<ReassignRequest>
|
|
1064
|
+
```
|
|
1065
|
+
Accept a reassign request. Moves the member to the target community. Only target community managers (or superusers) can accept. Permission: `communities:acceptReassignRequest`
|
|
1066
|
+
|
|
1067
|
+
```typescript
|
|
1068
|
+
rejectReassignRequest(payload: { id: number }): Promise<void>
|
|
1069
|
+
```
|
|
1070
|
+
Reject a reassign request. Only pending requests can be rejected. Permission: `communities:rejectReassignRequest`
|
|
1071
|
+
|
|
1072
|
+
### Communities Types
|
|
1073
|
+
|
|
1074
|
+
```typescript
|
|
1075
|
+
interface Community {
|
|
1076
|
+
id: number;
|
|
1077
|
+
name: string;
|
|
1078
|
+
description: string;
|
|
1079
|
+
slug: string;
|
|
1080
|
+
iconName: string;
|
|
1081
|
+
splashVideo: string | null;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
interface ListCommunitiesParams {
|
|
1085
|
+
limit?: number;
|
|
1086
|
+
offset?: number;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
type InternshipPassStatus = 'active' | 'revoked';
|
|
1090
|
+
|
|
1091
|
+
interface InternshipPass {
|
|
1092
|
+
id: number;
|
|
1093
|
+
email: string;
|
|
1094
|
+
firstName: string;
|
|
1095
|
+
lastName: string;
|
|
1096
|
+
community: number;
|
|
1097
|
+
communityName: string;
|
|
1098
|
+
status: InternshipPassStatus;
|
|
1099
|
+
createdAt: string;
|
|
1100
|
+
revokedAt: string | null;
|
|
1101
|
+
updatedAt: string;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
interface CreateInternshipPassRequest {
|
|
1105
|
+
email: string;
|
|
1106
|
+
firstName: string;
|
|
1107
|
+
lastName: string;
|
|
1108
|
+
community: number;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
interface ListInternshipPassesParams {
|
|
1112
|
+
limit?: number;
|
|
1113
|
+
offset?: number;
|
|
1114
|
+
includeRevoked?: boolean;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
type ReassignRequestStatus = 'pending' | 'accepted' | 'rejected';
|
|
1118
|
+
|
|
1119
|
+
interface ReassignRequest {
|
|
1120
|
+
id: number;
|
|
1121
|
+
requester: number;
|
|
1122
|
+
requesterEmail: string;
|
|
1123
|
+
member: number;
|
|
1124
|
+
memberEmail: string;
|
|
1125
|
+
targetCommunity: number;
|
|
1126
|
+
targetCommunityName: string;
|
|
1127
|
+
status: ReassignRequestStatus;
|
|
1128
|
+
createdAt: string;
|
|
1129
|
+
resolvedAt: string | null;
|
|
1130
|
+
resolvedBy: number | null;
|
|
1131
|
+
resolvedByEmail: string | null;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
interface CreateReassignRequestPayload {
|
|
1135
|
+
memberEmail: string;
|
|
1136
|
+
targetCommunity: number;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
interface ListReassignRequestsParams {
|
|
1140
|
+
limit?: number;
|
|
1141
|
+
offset?: number;
|
|
1142
|
+
}
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
---
|
|
1146
|
+
|
|
1147
|
+
## 9. Events Module
|
|
1148
|
+
|
|
1149
|
+
Access via `sdk.getEvents()`. Manage events, locations (event spaces and rooms), and room bookings.
|
|
1150
|
+
|
|
1151
|
+
### Methods
|
|
1152
|
+
|
|
1153
|
+
```typescript
|
|
1154
|
+
listEvents(payload?: ListEventsParams): Promise<PaginatedResponse<Event>>
|
|
1155
|
+
```
|
|
1156
|
+
List active events with optional filters (search, type, location, date range). Permission: `events:listEvents`
|
|
1157
|
+
|
|
1158
|
+
```typescript
|
|
1159
|
+
createEvent(payload: CreateEventRequest): Promise<Event>
|
|
1160
|
+
```
|
|
1161
|
+
Create a new event. Permission: `events:createEvent`
|
|
1162
|
+
|
|
1163
|
+
```typescript
|
|
1164
|
+
addEventHost(payload: { eventId: number; email: string }): Promise<Event>
|
|
1165
|
+
```
|
|
1166
|
+
Add a co-host to an event. Only the primary host can add co-hosts, and only to upcoming events. Permission: `events:addEventHost`
|
|
1167
|
+
|
|
1168
|
+
```typescript
|
|
1169
|
+
listLocations(payload?: ListLocationsParams): Promise<Location[]>
|
|
1170
|
+
```
|
|
1171
|
+
List available locations. Returns an array (not paginated). Optional `locationType` filter. Permission: `events:listLocations`
|
|
1172
|
+
|
|
1173
|
+
```typescript
|
|
1174
|
+
listRoomBookings(payload?: ListRoomBookingsParams): Promise<PaginatedResponse<RoomBooking>>
|
|
1175
|
+
```
|
|
1176
|
+
List approved room bookings with optional filters. Permission: `events:listRoomBookings`
|
|
1177
|
+
|
|
1178
|
+
```typescript
|
|
1179
|
+
createRoomBooking(payload: CreateRoomBookingRequest): Promise<RoomBooking>
|
|
1180
|
+
```
|
|
1181
|
+
Create a room booking. Location must be of type `'room'`. Permission: `events:createRoomBooking`
|
|
1182
|
+
|
|
1183
|
+
### Events Types
|
|
1184
|
+
|
|
1185
|
+
```typescript
|
|
1186
|
+
type EventType = 'public' | 'members_plus_one' | 'members_only' | 'community_only';
|
|
1187
|
+
type EventService = 'luma' | 'private' | 'test';
|
|
1188
|
+
type ReviewStatus = 'not_required' | 'approved' | 'rejected' | 'pending';
|
|
1189
|
+
type EventStatus = 'active' | 'suspended' | 'archived';
|
|
1190
|
+
type LocationType = 'event_space' | 'room';
|
|
1191
|
+
|
|
1192
|
+
interface Event {
|
|
1193
|
+
id: number;
|
|
1194
|
+
name: string;
|
|
1195
|
+
description: string;
|
|
1196
|
+
eventType: EventType;
|
|
1197
|
+
eventService: EventService;
|
|
1198
|
+
host: string;
|
|
1199
|
+
community: number | null;
|
|
1200
|
+
startsAt: string;
|
|
1201
|
+
endsAt: string;
|
|
1202
|
+
coverImage: string | null;
|
|
1203
|
+
eventId: string;
|
|
1204
|
+
location: string;
|
|
1205
|
+
locationName: string;
|
|
1206
|
+
displayLocation: string;
|
|
1207
|
+
url: string;
|
|
1208
|
+
additionalHosts: string[];
|
|
1209
|
+
color: string;
|
|
1210
|
+
reviewStatus: ReviewStatus;
|
|
1211
|
+
status: EventStatus;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
interface ListEventsParams {
|
|
1215
|
+
search?: string;
|
|
1216
|
+
eventType?: EventType;
|
|
1217
|
+
locationType?: LocationType;
|
|
1218
|
+
locationId?: string;
|
|
1219
|
+
date?: string; // YYYY-MM-DD
|
|
1220
|
+
startDate?: string; // YYYY-MM-DD
|
|
1221
|
+
endDate?: string; // YYYY-MM-DD
|
|
1222
|
+
page?: number;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
interface CreateEventRequest {
|
|
1226
|
+
name: string;
|
|
1227
|
+
eventType: EventType;
|
|
1228
|
+
startsAt: string; // ISO 8601
|
|
1229
|
+
endsAt: string; // ISO 8601
|
|
1230
|
+
location: string; // readable_id slug
|
|
1231
|
+
description?: string;
|
|
1232
|
+
coverImage?: string; // Base64 data URI
|
|
1233
|
+
additionalHosts?: string[];
|
|
1234
|
+
color?: string; // Hex color code
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
interface Location {
|
|
1238
|
+
id: number;
|
|
1239
|
+
owner: number | null;
|
|
1240
|
+
readableId: string;
|
|
1241
|
+
name: string;
|
|
1242
|
+
maxCapacity: number;
|
|
1243
|
+
description: string;
|
|
1244
|
+
directions: string;
|
|
1245
|
+
locationType: LocationType;
|
|
1246
|
+
warmupBuffer: string; // e.g. "00:10:00"
|
|
1247
|
+
cooldownBuffer: string; // e.g. "00:15:00"
|
|
1248
|
+
openBooking: boolean;
|
|
1249
|
+
floorLocation: string;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
interface ListLocationsParams {
|
|
1253
|
+
locationType?: LocationType;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
interface RoomBooking {
|
|
1257
|
+
id: number;
|
|
1258
|
+
startsAt: string;
|
|
1259
|
+
endsAt: string;
|
|
1260
|
+
location: string;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
interface ListRoomBookingsParams {
|
|
1264
|
+
locationId?: string;
|
|
1265
|
+
date?: string; // YYYY-MM-DD
|
|
1266
|
+
startDate?: string; // YYYY-MM-DD
|
|
1267
|
+
endDate?: string; // YYYY-MM-DD
|
|
1268
|
+
page?: number;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
interface CreateRoomBookingRequest {
|
|
1272
|
+
startsAt: string; // ISO 8601
|
|
1273
|
+
endsAt: string; // ISO 8601
|
|
1274
|
+
location: string; // readable_id (must be room type)
|
|
1275
|
+
}
|
|
1276
|
+
```
|
|
1277
|
+
|
|
1278
|
+
---
|
|
1279
|
+
|
|
1280
|
+
## 10. Offices Module
|
|
1281
|
+
|
|
1282
|
+
Access via `sdk.getOffices()`. Manage office access passes for membership contracts.
|
|
1283
|
+
|
|
1284
|
+
All endpoints require authentication, an active subscription, and manager status on the membership contract's organization (or superuser).
|
|
1285
|
+
|
|
1286
|
+
### Methods
|
|
1287
|
+
|
|
1288
|
+
```typescript
|
|
1289
|
+
createAccessPass(payload: CreateAccessPassRequest): Promise<AccessPass>
|
|
1290
|
+
```
|
|
1291
|
+
Create an access pass for a membership contract. Auto-creates an inactive account if the user does not exist. Each user can only have one active pass per contract. Permission: `offices:createAccessPass`
|
|
1292
|
+
|
|
1293
|
+
```typescript
|
|
1294
|
+
listAccessPasses(payload?: ListAccessPassesParams): Promise<PaginatedResponse<AccessPass>>
|
|
1295
|
+
```
|
|
1296
|
+
List access passes for contracts the user manages. Active only by default; set `includeRevoked: true` for all. Ordered newest first. Permission: `offices:listAccessPasses`
|
|
1297
|
+
|
|
1298
|
+
```typescript
|
|
1299
|
+
getAccessPass(payload: { id: number }): Promise<AccessPass>
|
|
1300
|
+
```
|
|
1301
|
+
Get an access pass by ID. Permission: `offices:getAccessPass`
|
|
1302
|
+
|
|
1303
|
+
```typescript
|
|
1304
|
+
revokeAccessPass(payload: { id: number }): Promise<void>
|
|
1305
|
+
```
|
|
1306
|
+
Revoke an access pass. Cannot revoke an already-revoked pass. Permission: `offices:revokeAccessPass`
|
|
1307
|
+
|
|
1308
|
+
### Offices Types
|
|
1309
|
+
|
|
1310
|
+
```typescript
|
|
1311
|
+
type AccessPassStatus = 'active' | 'revoked';
|
|
1312
|
+
|
|
1313
|
+
interface AccessPass {
|
|
1314
|
+
id: number;
|
|
1315
|
+
email: string;
|
|
1316
|
+
firstName: string;
|
|
1317
|
+
lastName: string;
|
|
1318
|
+
status: AccessPassStatus;
|
|
1319
|
+
membershipContract: number;
|
|
1320
|
+
contractReference: string;
|
|
1321
|
+
createdAt: string;
|
|
1322
|
+
revokedAt: string | null;
|
|
1323
|
+
updatedAt: string;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
interface CreateAccessPassRequest {
|
|
1327
|
+
email: string;
|
|
1328
|
+
firstName: string;
|
|
1329
|
+
lastName: string;
|
|
1330
|
+
membershipContract: number;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
interface ListAccessPassesParams {
|
|
1334
|
+
limit?: number;
|
|
1335
|
+
offset?: number;
|
|
1336
|
+
includeRevoked?: boolean;
|
|
1337
|
+
}
|
|
1338
|
+
```
|
|
1339
|
+
|
|
1340
|
+
---
|
|
1341
|
+
|
|
1342
|
+
## 11. Navigation Module
|
|
1343
|
+
|
|
1344
|
+
Access: `sdk.getNavigation()` returns `NavigationAccess`
|
|
1345
|
+
|
|
1346
|
+
App-to-app deep linking. Allows apps to navigate to other Frontier OS apps and receive incoming deep link data.
|
|
1347
|
+
|
|
1348
|
+
### Methods
|
|
1349
|
+
|
|
1350
|
+
#### `openApp(appId: string, options?: NavigationOpenAppOptions): Promise<void>`
|
|
1351
|
+
|
|
1352
|
+
Navigate the host to another app in the Frontier OS ecosystem.
|
|
1353
|
+
|
|
1354
|
+
- **Permission:** `navigation:openApp` or `navigation:*`
|
|
1355
|
+
- `appId` — target app ID from the Frontier app registry
|
|
1356
|
+
- `options.path` — optional deep link path for the target app
|
|
1357
|
+
- `options.params` — optional key-value params for the target app
|
|
1358
|
+
|
|
1359
|
+
#### `close(): Promise<void>`
|
|
1360
|
+
|
|
1361
|
+
Close the current app and return to the previous screen.
|
|
1362
|
+
|
|
1363
|
+
- **Permission:** `navigation:close` or `navigation:*`
|
|
1364
|
+
|
|
1365
|
+
#### `onDeepLink(callback: (data: DeepLinkData) => void): () => void`
|
|
1366
|
+
|
|
1367
|
+
Register a callback for incoming deep link data. Called when this app was opened via another app's `openApp()` call. Returns an unsubscribe function.
|
|
1368
|
+
|
|
1369
|
+
No permission required (passive listener).
|
|
1370
|
+
|
|
1371
|
+
### Types
|
|
1372
|
+
|
|
1373
|
+
```typescript
|
|
1374
|
+
interface NavigationOpenAppOptions {
|
|
1375
|
+
path?: string;
|
|
1376
|
+
params?: Record<string, string>;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
interface DeepLinkData {
|
|
1380
|
+
path?: string;
|
|
1381
|
+
params?: Record<string, string>;
|
|
1382
|
+
}
|
|
1383
|
+
```
|
|
1384
|
+
|
|
1385
|
+
### Permissions
|
|
1386
|
+
|
|
1387
|
+
| Permission | Description |
|
|
1388
|
+
|---|---|
|
|
1389
|
+
| `navigation:openApp` | Navigate to another app |
|
|
1390
|
+
| `navigation:close` | Close current app |
|
|
1391
|
+
| `navigation:*` | All navigation permissions |
|
|
1392
|
+
|
|
1393
|
+
---
|
|
1394
|
+
|
|
1395
|
+
## 12. UI Utilities
|
|
1396
|
+
|
|
1397
|
+
Import from `@frontiertower/frontier-sdk/ui-utils`.
|
|
1398
|
+
|
|
1399
|
+
### Detection
|
|
1400
|
+
|
|
1401
|
+
```typescript
|
|
1402
|
+
function isInFrontierApp(): boolean
|
|
1403
|
+
```
|
|
1404
|
+
Returns `true` if the window is embedded in an iframe (`window.self !== window.top`). Use to detect whether the app is running inside the Frontier Wallet host.
|
|
1405
|
+
|
|
1406
|
+
```typescript
|
|
1407
|
+
function getParentOrigin(): string | null
|
|
1408
|
+
```
|
|
1409
|
+
Returns the origin of the parent window (via `document.referrer` or `window.parent.location.origin`). Returns `null` if not in an iframe or origin cannot be determined.
|
|
1410
|
+
|
|
1411
|
+
### Standalone Fallback
|
|
1412
|
+
|
|
1413
|
+
```typescript
|
|
1414
|
+
function renderStandaloneMessage(container: HTMLElement, appName?: string): void
|
|
1415
|
+
```
|
|
1416
|
+
Renders a styled "Frontier Wallet Required" message into the given container element. Default `appName` is `'Frontier App'`. Directs users to `os.frontiertower.io` to install the app.
|
|
1417
|
+
|
|
1418
|
+
```typescript
|
|
1419
|
+
function createStandaloneHTML(appName?: string): string
|
|
1420
|
+
```
|
|
1421
|
+
Returns the same styled "Frontier Wallet Required" message as an HTML string (with gradient background). Default `appName` is `'Frontier App'`.
|
|
1422
|
+
|
|
1423
|
+
### Allowed Origins Constant
|
|
1424
|
+
|
|
1425
|
+
```typescript
|
|
1426
|
+
const ALLOWED_ORIGINS: string[] = [
|
|
1427
|
+
'http://localhost:5173',
|
|
1428
|
+
'https://sandbox.os.frontiertower.io',
|
|
1429
|
+
'https://alpha.os.frontiertower.io',
|
|
1430
|
+
'https://beta.os.frontiertower.io',
|
|
1431
|
+
'https://os.frontiertower.io',
|
|
1432
|
+
];
|
|
1433
|
+
```
|
|
1434
|
+
|
|
1435
|
+
---
|
|
1436
|
+
|
|
1437
|
+
## 12. Security
|
|
1438
|
+
|
|
1439
|
+
### Allowed Origins
|
|
1440
|
+
|
|
1441
|
+
The SDK defines five allowed Frontier Wallet origins. Apps should only accept messages from these:
|
|
1442
|
+
|
|
1443
|
+
| Environment | Origin |
|
|
1444
|
+
|---|---|
|
|
1445
|
+
| Development | `http://localhost:5173` |
|
|
1446
|
+
| Sandbox | `https://sandbox.os.frontiertower.io` |
|
|
1447
|
+
| Alpha | `https://alpha.os.frontiertower.io` |
|
|
1448
|
+
| Beta | `https://beta.os.frontiertower.io` |
|
|
1449
|
+
| Production | `https://os.frontiertower.io` |
|
|
1450
|
+
|
|
1451
|
+
### Access Controls Verification
|
|
1452
|
+
|
|
1453
|
+
The `user:getVerifiedAccessControls` method provides a tamper-proof way to verify user access. The flow:
|
|
1454
|
+
|
|
1455
|
+
1. The PWA host relays a `SignedAccessControls` envelope from the Frontier API server.
|
|
1456
|
+
2. The SDK decodes the Base64 payload, computes its SHA-256 hash, and verifies the ECDSA secp256k1 signature against a hardcoded public key for the current environment stage.
|
|
1457
|
+
3. If the signature is valid, the decoded `AccessControlsPayload` is returned.
|
|
1458
|
+
4. If invalid, the method throws -- the app should deny access.
|
|
1459
|
+
|
|
1460
|
+
Supported stages and their public keys (uncompressed secp256k1, hex):
|
|
1461
|
+
|
|
1462
|
+
| Stage(s) | Key |
|
|
1463
|
+
|---|---|
|
|
1464
|
+
| `test` | `04aab6c393...` (test-only key) |
|
|
1465
|
+
| `development`, `local`, `sandbox`, `staging` | `04dc3ab0e1...` (shared dev/sandbox key) |
|
|
1466
|
+
| `alpha`, `beta`, `production` | `045d1a0f9c...` (production key) |
|
|
1467
|
+
|
|
1468
|
+
**Rule: Always use `getVerifiedAccessControls()` for access-gating decisions.** Do not trust unsigned user data from other SDK methods for gating features, content, or permissions.
|
|
1469
|
+
|
|
1470
|
+
### PostMessage Security
|
|
1471
|
+
|
|
1472
|
+
- The SDK sends requests to `window.parent` with `'*'` as the target origin.
|
|
1473
|
+
- The SDK only processes responses where `event.source === window.parent`.
|
|
1474
|
+
- Requests auto-expire after 30 seconds.
|
|
1475
|
+
|
|
1476
|
+
---
|
|
1477
|
+
|
|
1478
|
+
## 13. Complete Permissions List (76 permissions across 9 modules)
|
|
1479
|
+
|
|
1480
|
+
### Wallet (23 permissions)
|
|
1481
|
+
|
|
1482
|
+
| Permission | Description |
|
|
1483
|
+
|---|---|
|
|
1484
|
+
| `wallet:getBalance` | Access wallet balance (raw bigint) |
|
|
1485
|
+
| `wallet:getBalanceFormatted` | Access formatted wallet balance (display strings) |
|
|
1486
|
+
| `wallet:getAddress` | Access wallet address |
|
|
1487
|
+
| `wallet:getSmartAccount` | Access smart account details |
|
|
1488
|
+
| `wallet:transferERC20` | Transfer ERC20 tokens |
|
|
1489
|
+
| `wallet:approveERC20` | Approve ERC20 token spending |
|
|
1490
|
+
| `wallet:transferNative` | Transfer native currency (ETH) |
|
|
1491
|
+
| `wallet:transferFrontierDollar` | Transfer FND (Frontier Network Dollar) |
|
|
1492
|
+
| `wallet:transferInternalFrontierDollar` | Transfer iFND (Internal Frontier Network Dollar) |
|
|
1493
|
+
| `wallet:transferOverallFrontierDollar` | Transfer using iFND first, fallback to FND |
|
|
1494
|
+
| `wallet:executeCall` | Execute arbitrary contract call |
|
|
1495
|
+
| `wallet:executeBatchCall` | Execute multiple contract calls atomically |
|
|
1496
|
+
| `wallet:getSupportedTokens` | Get supported token symbols for swaps |
|
|
1497
|
+
| `wallet:swap` | Execute token swap (same-chain or cross-chain) |
|
|
1498
|
+
| `wallet:quoteSwap` | Get swap quote without executing |
|
|
1499
|
+
| `wallet:getUsdDepositInstructions` | Get USD bank deposit instructions (on-ramp) |
|
|
1500
|
+
| `wallet:getEurDepositInstructions` | Get EUR/SEPA deposit instructions (on-ramp) |
|
|
1501
|
+
| `wallet:getLinkedBanks` | Get linked bank accounts (off-ramp) |
|
|
1502
|
+
| `wallet:linkUsBankAccount` | Link US bank account for USD withdrawals |
|
|
1503
|
+
| `wallet:linkEuroAccount` | Link EUR/IBAN bank account for EUR withdrawals |
|
|
1504
|
+
| `wallet:deleteLinkedBank` | Delete a linked bank account |
|
|
1505
|
+
| `wallet:getDeprecatedSmartAccounts` | Get deprecated smart accounts with active gas sponsorship |
|
|
1506
|
+
| `wallet:payWithFrontierDollar` | Pay via PaymentRouter with payment reference ID |
|
|
1507
|
+
|
|
1508
|
+
### Storage (4 permissions)
|
|
1509
|
+
|
|
1510
|
+
| Permission | Description |
|
|
1511
|
+
|---|---|
|
|
1512
|
+
| `storage:get` | Read from persistent storage |
|
|
1513
|
+
| `storage:set` | Write to persistent storage |
|
|
1514
|
+
| `storage:remove` | Remove key from persistent storage |
|
|
1515
|
+
| `storage:clear` | Clear all persistent storage |
|
|
1516
|
+
|
|
1517
|
+
### Chain (5 permissions)
|
|
1518
|
+
|
|
1519
|
+
| Permission | Description |
|
|
1520
|
+
|---|---|
|
|
1521
|
+
| `chain:getCurrentNetwork` | Get current network name |
|
|
1522
|
+
| `chain:getAvailableNetworks` | Get list of available networks |
|
|
1523
|
+
| `chain:switchNetwork` | Switch to a different network |
|
|
1524
|
+
| `chain:getCurrentChainConfig` | Get full chain configuration |
|
|
1525
|
+
| `chain:getContractAddresses` | Get FND, iFND, PaymentRouter, SubscriptionManager addresses |
|
|
1526
|
+
|
|
1527
|
+
### User (8 permissions)
|
|
1528
|
+
|
|
1529
|
+
| Permission | Description |
|
|
1530
|
+
|---|---|
|
|
1531
|
+
| `user:getDetails` | Access current user details |
|
|
1532
|
+
| `user:getProfile` | Access current user profile |
|
|
1533
|
+
| `user:getReferralOverview` | Access referral statistics |
|
|
1534
|
+
| `user:getReferralDetails` | Access detailed referral information |
|
|
1535
|
+
| `user:addUserContact` | Add user contact information |
|
|
1536
|
+
| `user:getOrCreateKyc` | Get or create KYC verification status |
|
|
1537
|
+
| `user:createSignupRequest` | Submit membership signup request with crypto payment |
|
|
1538
|
+
| `user:getVerifiedAccessControls` | Get cryptographically verified access controls |
|
|
1539
|
+
|
|
1540
|
+
### Communities (11 permissions)
|
|
1541
|
+
|
|
1542
|
+
| Permission | Description |
|
|
1543
|
+
|---|---|
|
|
1544
|
+
| `communities:listCommunities` | List all visible communities (paginated) |
|
|
1545
|
+
| `communities:getCommunity` | Get a community by ID or slug |
|
|
1546
|
+
| `communities:createInternshipPass` | Create an internship pass for a managed community |
|
|
1547
|
+
| `communities:listInternshipPasses` | List internship passes for managed communities |
|
|
1548
|
+
| `communities:getInternshipPass` | Retrieve an internship pass by ID |
|
|
1549
|
+
| `communities:revokeInternshipPass` | Revoke an internship pass |
|
|
1550
|
+
| `communities:createReassignRequest` | Create a member reassignment request |
|
|
1551
|
+
| `communities:listReassignRequests` | List pending reassignment requests |
|
|
1552
|
+
| `communities:getReassignRequest` | Retrieve a reassignment request by ID |
|
|
1553
|
+
| `communities:acceptReassignRequest` | Accept a reassignment request (moves member) |
|
|
1554
|
+
| `communities:rejectReassignRequest` | Reject a reassignment request |
|
|
1555
|
+
|
|
1556
|
+
### Partnerships (7 permissions)
|
|
1557
|
+
|
|
1558
|
+
| Permission | Description |
|
|
1559
|
+
|---|---|
|
|
1560
|
+
| `partnerships:listSponsors` | List sponsors you manage (paginated) |
|
|
1561
|
+
| `partnerships:getSponsor` | Retrieve a Sponsor by ID |
|
|
1562
|
+
| `partnerships:createSponsorPass` | Create a SponsorPass |
|
|
1563
|
+
| `partnerships:listActiveSponsorPasses` | List active SponsorPasses (paginated) |
|
|
1564
|
+
| `partnerships:listAllSponsorPasses` | List all SponsorPasses (paginated) |
|
|
1565
|
+
| `partnerships:getSponsorPass` | Retrieve a SponsorPass by ID |
|
|
1566
|
+
| `partnerships:revokeSponsorPass` | Revoke a SponsorPass |
|
|
1567
|
+
|
|
1568
|
+
### Third-Party (15 permissions)
|
|
1569
|
+
|
|
1570
|
+
| Permission | Description |
|
|
1571
|
+
|---|---|
|
|
1572
|
+
| `thirdParty:listDevelopers` | List developer accounts (paginated) |
|
|
1573
|
+
| `thirdParty:getDeveloper` | Get developer details by ID |
|
|
1574
|
+
| `thirdParty:updateDeveloper` | Update developer information |
|
|
1575
|
+
| `thirdParty:rotateDeveloperApiKey` | Rotate developer API key |
|
|
1576
|
+
| `thirdParty:listApps` | List registered apps (paginated) |
|
|
1577
|
+
| `thirdParty:createApp` | Register a new app |
|
|
1578
|
+
| `thirdParty:getApp` | Get app details by ID |
|
|
1579
|
+
| `thirdParty:updateApp` | Update an app |
|
|
1580
|
+
| `thirdParty:deleteApp` | Request app deactivation |
|
|
1581
|
+
| `thirdParty:listWebhooks` | List webhooks (paginated) |
|
|
1582
|
+
| `thirdParty:createWebhook` | Create a new webhook |
|
|
1583
|
+
| `thirdParty:getWebhook` | Get webhook details by ID |
|
|
1584
|
+
| `thirdParty:updateWebhook` | Update a webhook |
|
|
1585
|
+
| `thirdParty:deleteWebhook` | Delete a webhook |
|
|
1586
|
+
| `thirdParty:rotateWebhookSigningKey` | Rotate webhook signing key |
|
|
1587
|
+
|
|
1588
|
+
### Events (6 permissions)
|
|
1589
|
+
|
|
1590
|
+
| Permission | Description |
|
|
1591
|
+
|---|---|
|
|
1592
|
+
| `events:listEvents` | List events with optional filters (paginated) |
|
|
1593
|
+
| `events:createEvent` | Create a new event |
|
|
1594
|
+
| `events:addEventHost` | Add a co-host to an event |
|
|
1595
|
+
| `events:listLocations` | List available locations (event spaces and rooms) |
|
|
1596
|
+
| `events:listRoomBookings` | List room bookings (paginated) |
|
|
1597
|
+
| `events:createRoomBooking` | Create a room booking |
|
|
1598
|
+
|
|
1599
|
+
### Offices (4 permissions)
|
|
1600
|
+
|
|
1601
|
+
| Permission | Description |
|
|
1602
|
+
|---|---|
|
|
1603
|
+
| `offices:createAccessPass` | Create an access pass for a membership contract |
|
|
1604
|
+
| `offices:listAccessPasses` | List access passes for managed contracts (paginated) |
|
|
1605
|
+
| `offices:getAccessPass` | Retrieve an access pass by ID |
|
|
1606
|
+
| `offices:revokeAccessPass` | Revoke an access pass |
|
|
1607
|
+
|
|
1608
|
+
### Wildcard Permissions
|
|
1609
|
+
|
|
1610
|
+
Each module supports a wildcard permission that grants access to all methods in that module:
|
|
1611
|
+
|
|
1612
|
+
| Wildcard | Grants |
|
|
1613
|
+
|---|---|
|
|
1614
|
+
| `wallet:*` | All wallet permissions |
|
|
1615
|
+
| `storage:*` | All storage permissions |
|
|
1616
|
+
| `chain:*` | All chain permissions |
|
|
1617
|
+
| `user:*` | All user permissions |
|
|
1618
|
+
| `communities:*` | All communities permissions |
|
|
1619
|
+
| `partnerships:*` | All partnerships permissions |
|
|
1620
|
+
| `thirdParty:*` | All third-party permissions |
|
|
1621
|
+
| `events:*` | All events permissions |
|
|
1622
|
+
| `offices:*` | All offices permissions |
|