@solworks/poll-api-client 0.1.0 → 0.1.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/client.js CHANGED
@@ -72,11 +72,15 @@ export class PollClient {
72
72
  }
73
73
  // ── User ──────────────────────────────────────────────────────────────
74
74
  async getAccount() {
75
- return this.request('GET', '/api/user/account');
75
+ // API returns { user: {...}, address: string, error: null }
76
+ const res = await this.request('GET', '/api/user/account');
77
+ return { ...res.user, walletAddress: res.address };
76
78
  }
77
79
  async getProfile(uuid) {
80
+ // API returns { profile: {...}, stats: {...}, error: null }
78
81
  const path = uuid ? `/api/user/profile/${uuid}` : '/api/user/profile';
79
- return this.request('GET', path);
82
+ const res = await this.request('GET', path);
83
+ return { ...res.profile, stats: res.stats };
80
84
  }
81
85
  async updateDisplayName(name) {
82
86
  await this.request('POST', '/api/user/account/displayname', {
@@ -84,30 +88,40 @@ export class PollClient {
84
88
  });
85
89
  }
86
90
  async getXpBalance() {
91
+ // API returns { xp: number, error: null }
87
92
  return this.request('GET', '/api/user/balance');
88
93
  }
89
94
  async getUsdcBalance() {
90
- return this.request('GET', '/api/user/usdc/balance');
95
+ // API returns { balance: number, error: null } — field is "balance", not "usdc"
96
+ const res = await this.request('GET', '/api/user/usdc/balance');
97
+ return { usdc: res.balance, error: res.error };
91
98
  }
92
99
  // ── Bets ──────────────────────────────────────────────────────────────
100
+ // Bets endpoints use ResponseBuilder: { data: T, error: {...}, request: {...} }
93
101
  async listPublicBets(params) {
94
102
  const path = this.buildUrl('/api/bets-usdc/all/public', params);
95
- return this.request('GET', path);
103
+ const res = await this.request('GET', path);
104
+ return res.data;
96
105
  }
97
106
  async getTrendingBets() {
98
- return this.request('GET', '/api/bets-usdc/all/public/trending');
107
+ const res = await this.request('GET', '/api/bets-usdc/all/public/trending');
108
+ return res.data;
99
109
  }
100
110
  async getNewBets() {
101
- return this.request('GET', '/api/bets-usdc/all/public/new');
111
+ const res = await this.request('GET', '/api/bets-usdc/all/public/new');
112
+ return res.data;
102
113
  }
103
114
  async getBet(id) {
104
- return this.request('GET', `/api/bets-usdc/all/public/single/${id}`);
115
+ const res = await this.request('GET', `/api/bets-usdc/all/public/single/${id}`);
116
+ return res.data;
105
117
  }
106
118
  async getMyBets() {
107
- return this.request('GET', '/api/bets-usdc/mine');
119
+ const res = await this.request('GET', '/api/bets-usdc/mine');
120
+ return res.data;
108
121
  }
109
122
  async createBet(params) {
110
- return this.request('POST', '/api/bets-usdc', params);
123
+ const res = await this.request('POST', '/api/bets-usdc', params);
124
+ return res.data;
111
125
  }
112
126
  async joinBet(betAddress) {
113
127
  return this.request('POST', '/api/bets-usdc/join', { betAddress });
@@ -130,33 +144,44 @@ export class PollClient {
130
144
  return this.request('POST', '/api/bets-usdc/settle', { betAddress });
131
145
  }
132
146
  async getProbabilityHistory(betAddress) {
133
- return this.request('GET', `/api/bets-usdc/all/public/single/${betAddress}/probability-history`);
147
+ // API returns { data: { betAddress, dataPoints: [...] } }
148
+ const res = await this.request('GET', `/api/bets-usdc/all/public/single/${betAddress}/probability-history`);
149
+ return res.data.dataPoints;
134
150
  }
135
151
  // ── Wagers ────────────────────────────────────────────────────────────
136
152
  async getMyWagers(params) {
153
+ // API returns { data: [...], error: {...}, request: {...} }
137
154
  const path = this.buildUrl('/api/bets-usdc/wagers', params);
138
- return this.request('GET', path);
155
+ const res = await this.request('GET', path);
156
+ return res.data;
139
157
  }
140
158
  // ── Leaderboard ───────────────────────────────────────────────────────
141
159
  async getLeaderboard() {
142
- return this.request('GET', '/api/leaderboard');
160
+ // API returns { leaderboard: [...], pagination: {...} }
161
+ const res = await this.request('GET', '/api/leaderboard');
162
+ return res.leaderboard;
143
163
  }
144
164
  async getMyRanking() {
145
165
  return this.request('GET', '/api/leaderboard/me');
146
166
  }
147
167
  // ── Social ────────────────────────────────────────────────────────────
148
168
  async getFriends() {
149
- return this.request('GET', '/api/user/friends');
169
+ // API returns { friends: [...], totalCount, error }
170
+ const res = await this.request('GET', '/api/user/friends');
171
+ return res.friends;
150
172
  }
151
173
  async sendFriendRequest(uuid) {
152
- return this.request('POST', '/api/user/friends/request', { uuid });
174
+ // API expects { targetUserUuid } not { uuid }
175
+ return this.request('POST', '/api/user/friends/request', { targetUserUuid: uuid });
153
176
  }
154
177
  async respondFriendRequest(id, accept) {
155
178
  const action = accept ? 'accept' : 'decline';
156
179
  return this.request('PUT', `/api/user/friends/request/${id}/${action}`);
157
180
  }
158
181
  async getFavouriteBets() {
159
- return this.request('GET', '/api/user/favourites/bets');
182
+ // API returns { data: [...], error }
183
+ const res = await this.request('GET', '/api/user/favourites/bets');
184
+ return res.data;
160
185
  }
161
186
  async favouriteBet(betAddress) {
162
187
  return this.request('POST', '/api/user/favourites/bets', {
@@ -171,12 +196,16 @@ export class PollClient {
171
196
  }
172
197
  // ── Wallet ────────────────────────────────────────────────────────────
173
198
  async getWalletTransactions() {
174
- return this.request('GET', '/api/user/wallet/transactions');
199
+ // API returns { transactions: [...], error }
200
+ const res = await this.request('GET', '/api/user/wallet/transactions');
201
+ return res.transactions;
175
202
  }
176
203
  // ── Notifications ─────────────────────────────────────────────────────
177
204
  async getNotifications(params) {
205
+ // API returns { notifications: [...], unreadCount, totalCount, page, limit, hasMore, error }
178
206
  const path = this.buildUrl('/api/user/notifications', params);
179
- return this.request('GET', path);
207
+ const res = await this.request('GET', path);
208
+ return res.notifications;
180
209
  }
181
210
  async markNotificationRead(id) {
182
211
  return this.request('POST', '/api/user/notification/read', {
package/dist/types.d.ts CHANGED
@@ -22,16 +22,18 @@ export interface UserAccount {
22
22
  email: string | null;
23
23
  xpBalance: number;
24
24
  balance: number;
25
+ walletAddress?: string;
25
26
  [key: string]: unknown;
26
27
  }
27
28
  export interface UserProfile {
28
- id: number;
29
29
  uuid: string;
30
30
  displayName: string | null;
31
+ profileImageUrl: string | null;
32
+ stats?: Record<string, unknown>;
31
33
  [key: string]: unknown;
32
34
  }
33
35
  export interface Balance {
34
- xp: number;
36
+ xp?: number;
35
37
  usdc?: number;
36
38
  error: string | null;
37
39
  }
@@ -55,6 +57,8 @@ export interface Friend {
55
57
  id: number;
56
58
  uuid: string;
57
59
  displayName: string | null;
60
+ profileImageUrl: string | null;
61
+ friendsSince?: string;
58
62
  [key: string]: unknown;
59
63
  }
60
64
  export interface WalletTransaction {
@@ -66,10 +70,10 @@ export interface WalletTransaction {
66
70
  }
67
71
  export interface Notification {
68
72
  id: string;
69
- type: string;
73
+ eventType: string;
70
74
  title: string;
71
- body?: string;
72
- read: boolean;
75
+ description?: string;
76
+ readAt: string | null;
73
77
  createdAt: string;
74
78
  [key: string]: unknown;
75
79
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solworks/poll-api-client",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Typed HTTP client for the Poll.fun REST API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -3,6 +3,12 @@ import { PollClient } from '../../../src/client';
3
3
  import { createMockFetch, mockJsonResponse } from '../../helpers/mock-fetch';
4
4
  import { createBetFixture } from '../../fixtures';
5
5
 
6
+ // API bets endpoints return ResponseBuilder.success() wrapper:
7
+ // { data: T, error: { message: null, logs: [] }, request: { uuid, latency } }
8
+ function wrapResponse<T>(data: T) {
9
+ return { data, error: { message: null, logs: [] }, request: { uuid: 'req-123', latency: 10 } };
10
+ }
11
+
6
12
  describe('Bets endpoints', () => {
7
13
  let mockFetch: ReturnType<typeof createMockFetch>;
8
14
  let client: PollClient;
@@ -16,9 +22,9 @@ describe('Bets endpoints', () => {
16
22
  });
17
23
  });
18
24
 
19
- it('listPublicBets sends correct GET', async () => {
25
+ it('listPublicBets sends correct GET and unwraps data', async () => {
20
26
  const bets = [createBetFixture(), createBetFixture()];
21
- mockFetch.mockResolvedValue(mockJsonResponse(bets));
27
+ mockFetch.mockResolvedValue(mockJsonResponse(wrapResponse(bets)));
22
28
 
23
29
  const result = await client.listPublicBets();
24
30
 
@@ -30,7 +36,7 @@ describe('Bets endpoints', () => {
30
36
 
31
37
  it('listPublicBets with page param', async () => {
32
38
  const bets = [createBetFixture()];
33
- mockFetch.mockResolvedValue(mockJsonResponse(bets));
39
+ mockFetch.mockResolvedValue(mockJsonResponse(wrapResponse(bets)));
34
40
 
35
41
  await client.listPublicBets({ page: 2 });
36
42
 
@@ -38,9 +44,9 @@ describe('Bets endpoints', () => {
38
44
  expect(url).toBe('https://api.poll.fun/api/bets-usdc/all/public?page=2');
39
45
  });
40
46
 
41
- it('getTrendingBets sends correct GET', async () => {
47
+ it('getTrendingBets sends correct GET and unwraps data', async () => {
42
48
  const bets = [createBetFixture()];
43
- mockFetch.mockResolvedValue(mockJsonResponse(bets));
49
+ mockFetch.mockResolvedValue(mockJsonResponse(wrapResponse(bets)));
44
50
 
45
51
  const result = await client.getTrendingBets();
46
52
 
@@ -50,9 +56,9 @@ describe('Bets endpoints', () => {
50
56
  expect(init.method).toBe('GET');
51
57
  });
52
58
 
53
- it('getBet sends GET with ID', async () => {
59
+ it('getBet sends GET with ID and unwraps data', async () => {
54
60
  const bet = createBetFixture({ id: 'bet-123' });
55
- mockFetch.mockResolvedValue(mockJsonResponse(bet));
61
+ mockFetch.mockResolvedValue(mockJsonResponse(wrapResponse(bet)));
56
62
 
57
63
  const result = await client.getBet('bet-123');
58
64
 
@@ -62,9 +68,9 @@ describe('Bets endpoints', () => {
62
68
  expect(init.method).toBe('GET');
63
69
  });
64
70
 
65
- it('createBet sends POST with body', async () => {
71
+ it('createBet sends POST with body and unwraps data', async () => {
66
72
  const newBet = createBetFixture();
67
- mockFetch.mockResolvedValue(mockJsonResponse(newBet));
73
+ mockFetch.mockResolvedValue(mockJsonResponse(wrapResponse(newBet)));
68
74
 
69
75
  const params = {
70
76
  question: 'Will it rain tomorrow?',
@@ -15,12 +15,16 @@ describe('Leaderboard endpoints', () => {
15
15
  });
16
16
  });
17
17
 
18
- it('getLeaderboard sends correct GET', async () => {
18
+ it('getLeaderboard sends correct GET and unwraps leaderboard array', async () => {
19
19
  const entries = [
20
20
  { userId: 1, uuid: 'u1', displayName: 'User1', rank: 1, points: 1000 },
21
21
  { userId: 2, uuid: 'u2', displayName: 'User2', rank: 2, points: 800 },
22
22
  ];
23
- mockFetch.mockResolvedValue(mockJsonResponse(entries));
23
+ // API returns { leaderboard: [...], pagination: {...} }
24
+ mockFetch.mockResolvedValue(mockJsonResponse({
25
+ leaderboard: entries,
26
+ pagination: { total: 2, page: 1, limit: 50 },
27
+ }));
24
28
 
25
29
  const result = await client.getLeaderboard();
26
30
 
@@ -15,12 +15,13 @@ describe('Social endpoints', () => {
15
15
  });
16
16
  });
17
17
 
18
- it('getFriends sends correct GET', async () => {
18
+ it('getFriends sends correct GET and unwraps friends array', async () => {
19
19
  const friends = [
20
- { id: 1, uuid: 'f1', displayName: 'Friend1' },
21
- { id: 2, uuid: 'f2', displayName: 'Friend2' },
20
+ { id: 1, uuid: 'f1', displayName: 'Friend1', profileImageUrl: null },
21
+ { id: 2, uuid: 'f2', displayName: 'Friend2', profileImageUrl: null },
22
22
  ];
23
- mockFetch.mockResolvedValue(mockJsonResponse(friends));
23
+ // API returns { friends: [...], totalCount, error }
24
+ mockFetch.mockResolvedValue(mockJsonResponse({ friends, totalCount: 2, error: null }));
24
25
 
25
26
  const result = await client.getFriends();
26
27
 
@@ -30,7 +31,7 @@ describe('Social endpoints', () => {
30
31
  expect(init.method).toBe('GET');
31
32
  });
32
33
 
33
- it('sendFriendRequest sends POST', async () => {
34
+ it('sendFriendRequest sends POST with targetUserUuid', async () => {
34
35
  mockFetch.mockResolvedValue(mockJsonResponse({ success: true }));
35
36
 
36
37
  await client.sendFriendRequest('target-uuid');
@@ -38,7 +39,7 @@ describe('Social endpoints', () => {
38
39
  const [url, init] = mockFetch.mock.calls[0];
39
40
  expect(url).toBe('https://api.poll.fun/api/user/friends/request');
40
41
  expect(init.method).toBe('POST');
41
- expect(JSON.parse(init.body)).toEqual({ uuid: 'target-uuid' });
42
+ expect(JSON.parse(init.body)).toEqual({ targetUserUuid: 'target-uuid' });
42
43
  });
43
44
 
44
45
  it('favouriteBet sends POST', async () => {
@@ -16,36 +16,41 @@ describe('User endpoints', () => {
16
16
  });
17
17
  });
18
18
 
19
- it('getAccount sends correct GET', async () => {
19
+ it('getAccount sends correct GET and unwraps user + address', async () => {
20
20
  const user = createUserFixture();
21
- mockFetch.mockResolvedValue(mockJsonResponse(user));
21
+ const address = 'So1anaAddr3ss123';
22
+ // API returns { user: {...}, address: string, error: null }
23
+ mockFetch.mockResolvedValue(mockJsonResponse({ user, address, error: null }));
22
24
 
23
25
  const result = await client.getAccount();
24
26
 
25
- expect(result).toEqual(user);
27
+ expect(result).toEqual({ ...user, walletAddress: address });
26
28
  const [url, init] = mockFetch.mock.calls[0];
27
29
  expect(url).toBe('https://api.poll.fun/api/user/account');
28
30
  expect(init.method).toBe('GET');
29
31
  });
30
32
 
31
- it('getProfile without uuid', async () => {
32
- const profile = { id: 1, uuid: 'abc', displayName: 'Test' };
33
- mockFetch.mockResolvedValue(mockJsonResponse(profile));
33
+ it('getProfile without uuid unwraps profile + stats', async () => {
34
+ const profile = { uuid: 'abc', displayName: 'Test', profileImageUrl: null };
35
+ const stats = { betsCreated: 5, totalWagered: 100 };
36
+ // API returns { profile: {...}, stats: {...}, error: null }
37
+ mockFetch.mockResolvedValue(mockJsonResponse({ profile, stats, error: null }));
34
38
 
35
39
  const result = await client.getProfile();
36
40
 
37
- expect(result).toEqual(profile);
41
+ expect(result).toEqual({ ...profile, stats });
38
42
  const [url] = mockFetch.mock.calls[0];
39
43
  expect(url).toBe('https://api.poll.fun/api/user/profile');
40
44
  });
41
45
 
42
46
  it('getProfile with uuid sends GET /api/user/profile/:uuid', async () => {
43
- const profile = { id: 2, uuid: 'user-uuid-123', displayName: 'OtherUser' };
44
- mockFetch.mockResolvedValue(mockJsonResponse(profile));
47
+ const profile = { uuid: 'user-uuid-123', displayName: 'OtherUser', profileImageUrl: null };
48
+ const stats = { betsCreated: 10 };
49
+ mockFetch.mockResolvedValue(mockJsonResponse({ profile, stats, error: null }));
45
50
 
46
51
  const result = await client.getProfile('user-uuid-123');
47
52
 
48
- expect(result).toEqual(profile);
53
+ expect(result).toEqual({ ...profile, stats });
49
54
  const [url] = mockFetch.mock.calls[0];
50
55
  expect(url).toBe('https://api.poll.fun/api/user/profile/user-uuid-123');
51
56
  });
@@ -72,4 +77,16 @@ describe('User endpoints', () => {
72
77
  expect(url).toBe('https://api.poll.fun/api/user/balance');
73
78
  expect(init.method).toBe('GET');
74
79
  });
80
+
81
+ it('getUsdcBalance sends correct GET and maps balance to usdc', async () => {
82
+ // API returns { balance: number, error: null }
83
+ mockFetch.mockResolvedValue(mockJsonResponse({ balance: 250.5, error: null }));
84
+
85
+ const result = await client.getUsdcBalance();
86
+
87
+ expect(result).toEqual({ usdc: 250.5, error: null });
88
+ const [url, init] = mockFetch.mock.calls[0];
89
+ expect(url).toBe('https://api.poll.fun/api/user/usdc/balance');
90
+ expect(init.method).toBe('GET');
91
+ });
75
92
  });
@@ -15,7 +15,7 @@ describe('Wallet endpoints', () => {
15
15
  });
16
16
  });
17
17
 
18
- it('getWalletTransactions sends correct GET', async () => {
18
+ it('getWalletTransactions sends correct GET and unwraps transactions', async () => {
19
19
  const txns = [
20
20
  {
21
21
  signature: 'sig123',
@@ -30,7 +30,8 @@ describe('Wallet endpoints', () => {
30
30
  createdAt: '2026-01-02T00:00:00.000Z',
31
31
  },
32
32
  ];
33
- mockFetch.mockResolvedValue(mockJsonResponse(txns));
33
+ // API returns { transactions: [...], error: null }
34
+ mockFetch.mockResolvedValue(mockJsonResponse({ transactions: txns, error: null }));
34
35
 
35
36
  const result = await client.getWalletTransactions();
36
37