@fenelabs/fene-sdk 0.5.0 → 0.7.2
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.d.mts +83 -13
- package/dist/index.d.ts +83 -13
- package/dist/index.js +68 -9
- package/dist/index.mjs +68 -9
- package/package.json +11 -2
package/dist/index.d.mts
CHANGED
|
@@ -22,6 +22,10 @@ interface AuthResponse {
|
|
|
22
22
|
role: "validator" | "delegator";
|
|
23
23
|
expires_at: number;
|
|
24
24
|
}
|
|
25
|
+
interface RefreshResponse {
|
|
26
|
+
success: boolean;
|
|
27
|
+
expires_at?: number;
|
|
28
|
+
}
|
|
25
29
|
declare enum ValidatorStatus {
|
|
26
30
|
NOT_EXIST = 0,
|
|
27
31
|
CREATED = 1,
|
|
@@ -95,15 +99,13 @@ interface WhitelistCheckResponse {
|
|
|
95
99
|
}
|
|
96
100
|
interface GeoNode {
|
|
97
101
|
address: string;
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
city: string;
|
|
102
|
+
role: "validator" | "delegator";
|
|
103
|
+
lat: number;
|
|
104
|
+
lng: number;
|
|
102
105
|
country: string;
|
|
103
|
-
|
|
104
|
-
last_seen: string;
|
|
105
|
-
node_type: "validator" | "rpc" | "bootstrap";
|
|
106
|
+
city?: string;
|
|
106
107
|
online: boolean;
|
|
108
|
+
last_seen: number;
|
|
107
109
|
}
|
|
108
110
|
interface GeoStats {
|
|
109
111
|
total_nodes: number;
|
|
@@ -112,9 +114,51 @@ interface GeoStats {
|
|
|
112
114
|
cities: number;
|
|
113
115
|
}
|
|
114
116
|
interface GeoUpdateRequest {
|
|
117
|
+
lat: number;
|
|
118
|
+
lng: number;
|
|
119
|
+
}
|
|
120
|
+
interface GeoAutoDetectResponse {
|
|
121
|
+
success: boolean;
|
|
122
|
+
address: string;
|
|
123
|
+
role: "validator" | "delegator";
|
|
115
124
|
latitude: number;
|
|
116
125
|
longitude: number;
|
|
117
|
-
|
|
126
|
+
country: string;
|
|
127
|
+
city: string;
|
|
128
|
+
is_online: boolean;
|
|
129
|
+
}
|
|
130
|
+
interface UserProfile {
|
|
131
|
+
address: string;
|
|
132
|
+
roles: ("validator" | "delegator")[];
|
|
133
|
+
validator?: ValidatorProfileInfo;
|
|
134
|
+
delegations?: DelegationInfo[];
|
|
135
|
+
total_delegation_stake: string;
|
|
136
|
+
total_pending_rewards: string;
|
|
137
|
+
avatar_url?: string;
|
|
138
|
+
geo?: GeoLocation;
|
|
139
|
+
}
|
|
140
|
+
interface ValidatorProfileInfo {
|
|
141
|
+
address: string;
|
|
142
|
+
moniker: string;
|
|
143
|
+
self_stake: string;
|
|
144
|
+
total_stake: string;
|
|
145
|
+
commission_rate: number;
|
|
146
|
+
delegator_count: number;
|
|
147
|
+
claimable_reward: string;
|
|
148
|
+
apr: number;
|
|
149
|
+
}
|
|
150
|
+
interface DelegationInfo {
|
|
151
|
+
validator_address: string;
|
|
152
|
+
validator_moniker: string;
|
|
153
|
+
stake_amount: string;
|
|
154
|
+
pending_rewards: string;
|
|
155
|
+
apr: number;
|
|
156
|
+
}
|
|
157
|
+
interface GeoLocation {
|
|
158
|
+
lat: number;
|
|
159
|
+
lng: number;
|
|
160
|
+
country: string;
|
|
161
|
+
city?: string;
|
|
118
162
|
}
|
|
119
163
|
interface NetworkStats {
|
|
120
164
|
total_validators: number;
|
|
@@ -255,9 +299,9 @@ declare class ResonanceClient {
|
|
|
255
299
|
verify(params: AuthVerifyRequest): Promise<AuthResponse>;
|
|
256
300
|
/**
|
|
257
301
|
* Refresh the access token using the refresh token cookie.
|
|
258
|
-
* Returns
|
|
302
|
+
* Returns { success: boolean, expires_at?: number }
|
|
259
303
|
*/
|
|
260
|
-
refresh(): Promise<
|
|
304
|
+
refresh(): Promise<RefreshResponse>;
|
|
261
305
|
/**
|
|
262
306
|
* Logout and revoke current session.
|
|
263
307
|
*/
|
|
@@ -277,10 +321,36 @@ declare class ResonanceClient {
|
|
|
277
321
|
getReferralKey(key: string): Promise<ReferralKey>;
|
|
278
322
|
getValidatorKeys(address: Address): Promise<ReferralKey[]>;
|
|
279
323
|
checkWhitelist(data: WhitelistCheckRequest): Promise<WhitelistCheckResponse>;
|
|
280
|
-
|
|
281
|
-
|
|
324
|
+
/**
|
|
325
|
+
* Get user profile with roles, validator info, delegations, avatar, and geo
|
|
326
|
+
* @param address The user wallet address
|
|
327
|
+
*/
|
|
328
|
+
getUserProfile(address: Address): Promise<UserProfile>;
|
|
329
|
+
/**
|
|
330
|
+
* Get user avatar URL
|
|
331
|
+
* @param address The user wallet address
|
|
332
|
+
*/
|
|
333
|
+
getUserAvatar(address: Address): Promise<{
|
|
334
|
+
url: string;
|
|
335
|
+
}>;
|
|
336
|
+
/**
|
|
337
|
+
* Upload user avatar
|
|
338
|
+
* @param address The user wallet address (must match authenticated user)
|
|
339
|
+
* @param file The image file to upload (png, jpg, or webp)
|
|
340
|
+
*/
|
|
341
|
+
uploadUserAvatar(address: Address, file: File): Promise<UploadResponse>;
|
|
342
|
+
/**
|
|
343
|
+
* Get all geo nodes, optionally filtered by role
|
|
344
|
+
* @param role Optional filter: "validator" or "delegator"
|
|
345
|
+
*/
|
|
346
|
+
getGeoNodes(role?: "validator" | "delegator"): Promise<GeoNode[]>;
|
|
282
347
|
getGeoStats(): Promise<GeoStats>;
|
|
283
348
|
updateGeoLocation(data: GeoUpdateRequest): Promise<void>;
|
|
349
|
+
/**
|
|
350
|
+
* Auto-detect user geo location from IP and save to server.
|
|
351
|
+
* Should be called after successful login.
|
|
352
|
+
*/
|
|
353
|
+
autoDetectGeo(): Promise<GeoAutoDetectResponse>;
|
|
284
354
|
getNetworkStats(): Promise<NetworkStats>;
|
|
285
355
|
getCurrentEpoch(): Promise<EpochInfo>;
|
|
286
356
|
getNetworkAPR(): Promise<NetworkAPR>;
|
|
@@ -375,4 +445,4 @@ declare class EventBus {
|
|
|
375
445
|
}
|
|
376
446
|
declare const eventBus: EventBus;
|
|
377
447
|
|
|
378
|
-
export { type APIErrorResponse, type Address, type AuthResponse, type AuthVerifyRequest, type AvatarResponse, type DailyBlockStats, type Delegator, type DelegatorRewards, type DelegatorStake, DelegatorStatus, type EpochInfo, ErrorCode, type ErrorCodeType, type GeoNode, type GeoStats, type GeoUpdateRequest, type NetworkAPR, type NetworkStats, type NonceResponse, type PaginatedResponse, type PriceResponse, type ReferralKey, type RequestContext, ResonanceClient, type ResonanceClientConfig, ResonanceError, type ResponseContext, type RewardHistory, type Transaction, type TransactionStats, type TransactionsList, type TransactionsParams, type UploadResponse, type Validator, type ValidatorAPR, ValidatorStatus, type ValidatorSummary, type WhitelistCheckRequest, type WhitelistCheckResponse, createResonanceClient, eventBus, hasErrorCode, isAuthError, isNetworkError, isNotFoundError, isResonanceError };
|
|
448
|
+
export { type APIErrorResponse, type Address, type AuthResponse, type AuthVerifyRequest, type AvatarResponse, type DailyBlockStats, type Delegator, type DelegatorRewards, type DelegatorStake, DelegatorStatus, type EpochInfo, ErrorCode, type ErrorCodeType, type GeoNode, type GeoStats, type GeoUpdateRequest, type NetworkAPR, type NetworkStats, type NonceResponse, type PaginatedResponse, type PriceResponse, type ReferralKey, type RefreshResponse, type RequestContext, ResonanceClient, type ResonanceClientConfig, ResonanceError, type ResponseContext, type RewardHistory, type Transaction, type TransactionStats, type TransactionsList, type TransactionsParams, type UploadResponse, type Validator, type ValidatorAPR, ValidatorStatus, type ValidatorSummary, type WhitelistCheckRequest, type WhitelistCheckResponse, createResonanceClient, eventBus, hasErrorCode, isAuthError, isNetworkError, isNotFoundError, isResonanceError };
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,10 @@ interface AuthResponse {
|
|
|
22
22
|
role: "validator" | "delegator";
|
|
23
23
|
expires_at: number;
|
|
24
24
|
}
|
|
25
|
+
interface RefreshResponse {
|
|
26
|
+
success: boolean;
|
|
27
|
+
expires_at?: number;
|
|
28
|
+
}
|
|
25
29
|
declare enum ValidatorStatus {
|
|
26
30
|
NOT_EXIST = 0,
|
|
27
31
|
CREATED = 1,
|
|
@@ -95,15 +99,13 @@ interface WhitelistCheckResponse {
|
|
|
95
99
|
}
|
|
96
100
|
interface GeoNode {
|
|
97
101
|
address: string;
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
city: string;
|
|
102
|
+
role: "validator" | "delegator";
|
|
103
|
+
lat: number;
|
|
104
|
+
lng: number;
|
|
102
105
|
country: string;
|
|
103
|
-
|
|
104
|
-
last_seen: string;
|
|
105
|
-
node_type: "validator" | "rpc" | "bootstrap";
|
|
106
|
+
city?: string;
|
|
106
107
|
online: boolean;
|
|
108
|
+
last_seen: number;
|
|
107
109
|
}
|
|
108
110
|
interface GeoStats {
|
|
109
111
|
total_nodes: number;
|
|
@@ -112,9 +114,51 @@ interface GeoStats {
|
|
|
112
114
|
cities: number;
|
|
113
115
|
}
|
|
114
116
|
interface GeoUpdateRequest {
|
|
117
|
+
lat: number;
|
|
118
|
+
lng: number;
|
|
119
|
+
}
|
|
120
|
+
interface GeoAutoDetectResponse {
|
|
121
|
+
success: boolean;
|
|
122
|
+
address: string;
|
|
123
|
+
role: "validator" | "delegator";
|
|
115
124
|
latitude: number;
|
|
116
125
|
longitude: number;
|
|
117
|
-
|
|
126
|
+
country: string;
|
|
127
|
+
city: string;
|
|
128
|
+
is_online: boolean;
|
|
129
|
+
}
|
|
130
|
+
interface UserProfile {
|
|
131
|
+
address: string;
|
|
132
|
+
roles: ("validator" | "delegator")[];
|
|
133
|
+
validator?: ValidatorProfileInfo;
|
|
134
|
+
delegations?: DelegationInfo[];
|
|
135
|
+
total_delegation_stake: string;
|
|
136
|
+
total_pending_rewards: string;
|
|
137
|
+
avatar_url?: string;
|
|
138
|
+
geo?: GeoLocation;
|
|
139
|
+
}
|
|
140
|
+
interface ValidatorProfileInfo {
|
|
141
|
+
address: string;
|
|
142
|
+
moniker: string;
|
|
143
|
+
self_stake: string;
|
|
144
|
+
total_stake: string;
|
|
145
|
+
commission_rate: number;
|
|
146
|
+
delegator_count: number;
|
|
147
|
+
claimable_reward: string;
|
|
148
|
+
apr: number;
|
|
149
|
+
}
|
|
150
|
+
interface DelegationInfo {
|
|
151
|
+
validator_address: string;
|
|
152
|
+
validator_moniker: string;
|
|
153
|
+
stake_amount: string;
|
|
154
|
+
pending_rewards: string;
|
|
155
|
+
apr: number;
|
|
156
|
+
}
|
|
157
|
+
interface GeoLocation {
|
|
158
|
+
lat: number;
|
|
159
|
+
lng: number;
|
|
160
|
+
country: string;
|
|
161
|
+
city?: string;
|
|
118
162
|
}
|
|
119
163
|
interface NetworkStats {
|
|
120
164
|
total_validators: number;
|
|
@@ -255,9 +299,9 @@ declare class ResonanceClient {
|
|
|
255
299
|
verify(params: AuthVerifyRequest): Promise<AuthResponse>;
|
|
256
300
|
/**
|
|
257
301
|
* Refresh the access token using the refresh token cookie.
|
|
258
|
-
* Returns
|
|
302
|
+
* Returns { success: boolean, expires_at?: number }
|
|
259
303
|
*/
|
|
260
|
-
refresh(): Promise<
|
|
304
|
+
refresh(): Promise<RefreshResponse>;
|
|
261
305
|
/**
|
|
262
306
|
* Logout and revoke current session.
|
|
263
307
|
*/
|
|
@@ -277,10 +321,36 @@ declare class ResonanceClient {
|
|
|
277
321
|
getReferralKey(key: string): Promise<ReferralKey>;
|
|
278
322
|
getValidatorKeys(address: Address): Promise<ReferralKey[]>;
|
|
279
323
|
checkWhitelist(data: WhitelistCheckRequest): Promise<WhitelistCheckResponse>;
|
|
280
|
-
|
|
281
|
-
|
|
324
|
+
/**
|
|
325
|
+
* Get user profile with roles, validator info, delegations, avatar, and geo
|
|
326
|
+
* @param address The user wallet address
|
|
327
|
+
*/
|
|
328
|
+
getUserProfile(address: Address): Promise<UserProfile>;
|
|
329
|
+
/**
|
|
330
|
+
* Get user avatar URL
|
|
331
|
+
* @param address The user wallet address
|
|
332
|
+
*/
|
|
333
|
+
getUserAvatar(address: Address): Promise<{
|
|
334
|
+
url: string;
|
|
335
|
+
}>;
|
|
336
|
+
/**
|
|
337
|
+
* Upload user avatar
|
|
338
|
+
* @param address The user wallet address (must match authenticated user)
|
|
339
|
+
* @param file The image file to upload (png, jpg, or webp)
|
|
340
|
+
*/
|
|
341
|
+
uploadUserAvatar(address: Address, file: File): Promise<UploadResponse>;
|
|
342
|
+
/**
|
|
343
|
+
* Get all geo nodes, optionally filtered by role
|
|
344
|
+
* @param role Optional filter: "validator" or "delegator"
|
|
345
|
+
*/
|
|
346
|
+
getGeoNodes(role?: "validator" | "delegator"): Promise<GeoNode[]>;
|
|
282
347
|
getGeoStats(): Promise<GeoStats>;
|
|
283
348
|
updateGeoLocation(data: GeoUpdateRequest): Promise<void>;
|
|
349
|
+
/**
|
|
350
|
+
* Auto-detect user geo location from IP and save to server.
|
|
351
|
+
* Should be called after successful login.
|
|
352
|
+
*/
|
|
353
|
+
autoDetectGeo(): Promise<GeoAutoDetectResponse>;
|
|
284
354
|
getNetworkStats(): Promise<NetworkStats>;
|
|
285
355
|
getCurrentEpoch(): Promise<EpochInfo>;
|
|
286
356
|
getNetworkAPR(): Promise<NetworkAPR>;
|
|
@@ -375,4 +445,4 @@ declare class EventBus {
|
|
|
375
445
|
}
|
|
376
446
|
declare const eventBus: EventBus;
|
|
377
447
|
|
|
378
|
-
export { type APIErrorResponse, type Address, type AuthResponse, type AuthVerifyRequest, type AvatarResponse, type DailyBlockStats, type Delegator, type DelegatorRewards, type DelegatorStake, DelegatorStatus, type EpochInfo, ErrorCode, type ErrorCodeType, type GeoNode, type GeoStats, type GeoUpdateRequest, type NetworkAPR, type NetworkStats, type NonceResponse, type PaginatedResponse, type PriceResponse, type ReferralKey, type RequestContext, ResonanceClient, type ResonanceClientConfig, ResonanceError, type ResponseContext, type RewardHistory, type Transaction, type TransactionStats, type TransactionsList, type TransactionsParams, type UploadResponse, type Validator, type ValidatorAPR, ValidatorStatus, type ValidatorSummary, type WhitelistCheckRequest, type WhitelistCheckResponse, createResonanceClient, eventBus, hasErrorCode, isAuthError, isNetworkError, isNotFoundError, isResonanceError };
|
|
448
|
+
export { type APIErrorResponse, type Address, type AuthResponse, type AuthVerifyRequest, type AvatarResponse, type DailyBlockStats, type Delegator, type DelegatorRewards, type DelegatorStake, DelegatorStatus, type EpochInfo, ErrorCode, type ErrorCodeType, type GeoNode, type GeoStats, type GeoUpdateRequest, type NetworkAPR, type NetworkStats, type NonceResponse, type PaginatedResponse, type PriceResponse, type ReferralKey, type RefreshResponse, type RequestContext, ResonanceClient, type ResonanceClientConfig, ResonanceError, type ResponseContext, type RewardHistory, type Transaction, type TransactionStats, type TransactionsList, type TransactionsParams, type UploadResponse, type Validator, type ValidatorAPR, ValidatorStatus, type ValidatorSummary, type WhitelistCheckRequest, type WhitelistCheckResponse, createResonanceClient, eventBus, hasErrorCode, isAuthError, isNetworkError, isNotFoundError, isResonanceError };
|
package/dist/index.js
CHANGED
|
@@ -349,7 +349,7 @@ var ResonanceClient = class {
|
|
|
349
349
|
}
|
|
350
350
|
/**
|
|
351
351
|
* Refresh the access token using the refresh token cookie.
|
|
352
|
-
* Returns
|
|
352
|
+
* Returns { success: boolean, expires_at?: number }
|
|
353
353
|
*/
|
|
354
354
|
async refresh() {
|
|
355
355
|
try {
|
|
@@ -361,11 +361,14 @@ var ResonanceClient = class {
|
|
|
361
361
|
});
|
|
362
362
|
if (response.ok) {
|
|
363
363
|
const data = await response.json();
|
|
364
|
-
return
|
|
364
|
+
return {
|
|
365
|
+
success: data.success === true,
|
|
366
|
+
expires_at: data.expires_at
|
|
367
|
+
};
|
|
365
368
|
}
|
|
366
|
-
return false;
|
|
369
|
+
return { success: false };
|
|
367
370
|
} catch {
|
|
368
|
-
return false;
|
|
371
|
+
return { success: false };
|
|
369
372
|
}
|
|
370
373
|
}
|
|
371
374
|
/**
|
|
@@ -442,13 +445,60 @@ var ResonanceClient = class {
|
|
|
442
445
|
});
|
|
443
446
|
}
|
|
444
447
|
// ============================================
|
|
445
|
-
//
|
|
448
|
+
// User Profile
|
|
446
449
|
// ============================================
|
|
447
|
-
|
|
448
|
-
|
|
450
|
+
/**
|
|
451
|
+
* Get user profile with roles, validator info, delegations, avatar, and geo
|
|
452
|
+
* @param address The user wallet address
|
|
453
|
+
*/
|
|
454
|
+
async getUserProfile(address) {
|
|
455
|
+
return this.request(`/eth/v1/user/${address}/profile`);
|
|
449
456
|
}
|
|
450
|
-
|
|
451
|
-
|
|
457
|
+
/**
|
|
458
|
+
* Get user avatar URL
|
|
459
|
+
* @param address The user wallet address
|
|
460
|
+
*/
|
|
461
|
+
async getUserAvatar(address) {
|
|
462
|
+
return this.request(`/eth/v1/user/${address}/avatar`);
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Upload user avatar
|
|
466
|
+
* @param address The user wallet address (must match authenticated user)
|
|
467
|
+
* @param file The image file to upload (png, jpg, or webp)
|
|
468
|
+
*/
|
|
469
|
+
async uploadUserAvatar(address, file) {
|
|
470
|
+
const formData = new FormData();
|
|
471
|
+
formData.append("file", file);
|
|
472
|
+
const response = await fetch(
|
|
473
|
+
`${this.baseUrl}/eth/v1/user/${address}/avatar`,
|
|
474
|
+
{
|
|
475
|
+
method: "POST",
|
|
476
|
+
credentials: "include",
|
|
477
|
+
// Send httpOnly cookies
|
|
478
|
+
body: formData
|
|
479
|
+
}
|
|
480
|
+
);
|
|
481
|
+
if (!response.ok) {
|
|
482
|
+
const error = await response.json().catch(() => ({ error: "Upload failed" }));
|
|
483
|
+
throw new ResonanceError(
|
|
484
|
+
"UPLOAD_FAILED",
|
|
485
|
+
error.error || "Failed to upload avatar",
|
|
486
|
+
void 0,
|
|
487
|
+
response.status
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
return response.json();
|
|
491
|
+
}
|
|
492
|
+
// ============================================
|
|
493
|
+
// Geo
|
|
494
|
+
// ============================================
|
|
495
|
+
/**
|
|
496
|
+
* Get all geo nodes, optionally filtered by role
|
|
497
|
+
* @param role Optional filter: "validator" or "delegator"
|
|
498
|
+
*/
|
|
499
|
+
async getGeoNodes(role) {
|
|
500
|
+
const params = role ? `?role=${role}` : "";
|
|
501
|
+
return this.request(`/eth/v1/geo/nodes${params}`);
|
|
452
502
|
}
|
|
453
503
|
async getGeoStats() {
|
|
454
504
|
return this.request("/eth/v1/geo/stats");
|
|
@@ -459,6 +509,15 @@ var ResonanceClient = class {
|
|
|
459
509
|
body: JSON.stringify(data)
|
|
460
510
|
});
|
|
461
511
|
}
|
|
512
|
+
/**
|
|
513
|
+
* Auto-detect user geo location from IP and save to server.
|
|
514
|
+
* Should be called after successful login.
|
|
515
|
+
*/
|
|
516
|
+
async autoDetectGeo() {
|
|
517
|
+
return this.request("/eth/v1/geo/auto-detect", {
|
|
518
|
+
method: "POST"
|
|
519
|
+
});
|
|
520
|
+
}
|
|
462
521
|
// ============================================
|
|
463
522
|
// Stats
|
|
464
523
|
// ============================================
|
package/dist/index.mjs
CHANGED
|
@@ -313,7 +313,7 @@ var ResonanceClient = class {
|
|
|
313
313
|
}
|
|
314
314
|
/**
|
|
315
315
|
* Refresh the access token using the refresh token cookie.
|
|
316
|
-
* Returns
|
|
316
|
+
* Returns { success: boolean, expires_at?: number }
|
|
317
317
|
*/
|
|
318
318
|
async refresh() {
|
|
319
319
|
try {
|
|
@@ -325,11 +325,14 @@ var ResonanceClient = class {
|
|
|
325
325
|
});
|
|
326
326
|
if (response.ok) {
|
|
327
327
|
const data = await response.json();
|
|
328
|
-
return
|
|
328
|
+
return {
|
|
329
|
+
success: data.success === true,
|
|
330
|
+
expires_at: data.expires_at
|
|
331
|
+
};
|
|
329
332
|
}
|
|
330
|
-
return false;
|
|
333
|
+
return { success: false };
|
|
331
334
|
} catch {
|
|
332
|
-
return false;
|
|
335
|
+
return { success: false };
|
|
333
336
|
}
|
|
334
337
|
}
|
|
335
338
|
/**
|
|
@@ -406,13 +409,60 @@ var ResonanceClient = class {
|
|
|
406
409
|
});
|
|
407
410
|
}
|
|
408
411
|
// ============================================
|
|
409
|
-
//
|
|
412
|
+
// User Profile
|
|
410
413
|
// ============================================
|
|
411
|
-
|
|
412
|
-
|
|
414
|
+
/**
|
|
415
|
+
* Get user profile with roles, validator info, delegations, avatar, and geo
|
|
416
|
+
* @param address The user wallet address
|
|
417
|
+
*/
|
|
418
|
+
async getUserProfile(address) {
|
|
419
|
+
return this.request(`/eth/v1/user/${address}/profile`);
|
|
413
420
|
}
|
|
414
|
-
|
|
415
|
-
|
|
421
|
+
/**
|
|
422
|
+
* Get user avatar URL
|
|
423
|
+
* @param address The user wallet address
|
|
424
|
+
*/
|
|
425
|
+
async getUserAvatar(address) {
|
|
426
|
+
return this.request(`/eth/v1/user/${address}/avatar`);
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Upload user avatar
|
|
430
|
+
* @param address The user wallet address (must match authenticated user)
|
|
431
|
+
* @param file The image file to upload (png, jpg, or webp)
|
|
432
|
+
*/
|
|
433
|
+
async uploadUserAvatar(address, file) {
|
|
434
|
+
const formData = new FormData();
|
|
435
|
+
formData.append("file", file);
|
|
436
|
+
const response = await fetch(
|
|
437
|
+
`${this.baseUrl}/eth/v1/user/${address}/avatar`,
|
|
438
|
+
{
|
|
439
|
+
method: "POST",
|
|
440
|
+
credentials: "include",
|
|
441
|
+
// Send httpOnly cookies
|
|
442
|
+
body: formData
|
|
443
|
+
}
|
|
444
|
+
);
|
|
445
|
+
if (!response.ok) {
|
|
446
|
+
const error = await response.json().catch(() => ({ error: "Upload failed" }));
|
|
447
|
+
throw new ResonanceError(
|
|
448
|
+
"UPLOAD_FAILED",
|
|
449
|
+
error.error || "Failed to upload avatar",
|
|
450
|
+
void 0,
|
|
451
|
+
response.status
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
return response.json();
|
|
455
|
+
}
|
|
456
|
+
// ============================================
|
|
457
|
+
// Geo
|
|
458
|
+
// ============================================
|
|
459
|
+
/**
|
|
460
|
+
* Get all geo nodes, optionally filtered by role
|
|
461
|
+
* @param role Optional filter: "validator" or "delegator"
|
|
462
|
+
*/
|
|
463
|
+
async getGeoNodes(role) {
|
|
464
|
+
const params = role ? `?role=${role}` : "";
|
|
465
|
+
return this.request(`/eth/v1/geo/nodes${params}`);
|
|
416
466
|
}
|
|
417
467
|
async getGeoStats() {
|
|
418
468
|
return this.request("/eth/v1/geo/stats");
|
|
@@ -423,6 +473,15 @@ var ResonanceClient = class {
|
|
|
423
473
|
body: JSON.stringify(data)
|
|
424
474
|
});
|
|
425
475
|
}
|
|
476
|
+
/**
|
|
477
|
+
* Auto-detect user geo location from IP and save to server.
|
|
478
|
+
* Should be called after successful login.
|
|
479
|
+
*/
|
|
480
|
+
async autoDetectGeo() {
|
|
481
|
+
return this.request("/eth/v1/geo/auto-detect", {
|
|
482
|
+
method: "POST"
|
|
483
|
+
});
|
|
484
|
+
}
|
|
426
485
|
// ============================================
|
|
427
486
|
// Stats
|
|
428
487
|
// ============================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fenelabs/fene-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "TypeScript SDK for Fene API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
21
21
|
"lint": "tsc --noEmit",
|
|
22
22
|
"test": "vitest run",
|
|
23
|
+
"watch": "esbuild src/app.ts --bundle --sourcemap --outdir=www --servedir=www --watch",
|
|
23
24
|
"prepublishOnly": "pnpm run build"
|
|
24
25
|
},
|
|
25
26
|
"keywords": [
|
|
@@ -33,9 +34,17 @@
|
|
|
33
34
|
"license": "MIT",
|
|
34
35
|
"repository": {
|
|
35
36
|
"type": "git",
|
|
36
|
-
"url": "https://github.com/fenelabs/fene-sdk"
|
|
37
|
+
"url": "https://github.com/fenelabs/fene-sdk.git"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"registry": "https://registry.npmjs.org/",
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"esbuild": ">=0.25.0"
|
|
37
45
|
},
|
|
38
46
|
"devDependencies": {
|
|
47
|
+
"esbuild": "^0.25.2",
|
|
39
48
|
"@types/node": "^25.0.3",
|
|
40
49
|
"tsup": "^8.0.0",
|
|
41
50
|
"typescript": "^5.3.0",
|