@puul/partner-sdk 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -63,6 +63,10 @@ interface PlacePredictionParams {
63
63
  stakeAmount: number;
64
64
  stakeCurrency: Currency;
65
65
  idempotencyKey: string;
66
+ /** Linked Puul user UUID (provide userId or userExternalId) */
67
+ userId?: string;
68
+ /** Your linked external user ID (provide userId or userExternalId) */
69
+ userExternalId?: string;
66
70
  /** Optional quote ID for slippage protection */
67
71
  quoteId?: string;
68
72
  /** Optional FX quote ID */
@@ -75,6 +79,10 @@ interface CreateQuoteParams {
75
79
  outcomeId: string;
76
80
  stakeAmount: number;
77
81
  stakeCurrency: Currency;
82
+ /** Linked Puul user UUID (provide userId or userExternalId) */
83
+ userId?: string;
84
+ /** Your linked external user ID (provide userId or userExternalId) */
85
+ userExternalId?: string;
78
86
  }
79
87
  interface QuoteResponse {
80
88
  quoteId: string;
@@ -153,6 +161,10 @@ interface DepositParams {
153
161
  currency?: string;
154
162
  idempotency_key: string;
155
163
  reference?: string;
164
+ /** Linked Puul user UUID (provide userId or userExternalId) */
165
+ userId?: string;
166
+ /** Your linked external user ID (provide userId or userExternalId) */
167
+ userExternalId?: string;
156
168
  }
157
169
  type WithdrawMethod = 'bank' | 'crypto';
158
170
  interface WithdrawParams {
@@ -172,7 +184,85 @@ interface WithdrawResult {
172
184
  payoutReference: string | null;
173
185
  status: string;
174
186
  }
175
- type WebhookEventType = 'user.created' | 'prediction.placed' | 'prediction.settled' | 'prediction.voided' | 'market.closed' | 'market.settled' | 'deposit.confirmed' | 'withdrawal.completed' | 'withdrawal.failed';
187
+ type LotteryPoolType = 'winner_takes_all' | 'tiered';
188
+ type LotteryPoolFrequency = 'daily' | 'weekly' | 'monthly' | 'quarterly';
189
+ type LotteryPoolStatus = 'upcoming' | 'open' | 'drawing' | 'settled' | 'cancelled';
190
+ type LotteryEntryStatus = 'active' | 'won' | 'lost' | 'refunded';
191
+ interface PrizeTier {
192
+ /** 1-based rank (1 = first place) */
193
+ rank: number;
194
+ /** Percentage of distributable pool in basis points (5000 = 50%) */
195
+ pct: number;
196
+ }
197
+ interface LotteryPool {
198
+ id: string;
199
+ title: string;
200
+ description: string | null;
201
+ type: LotteryPoolType;
202
+ frequency: LotteryPoolFrequency;
203
+ status: LotteryPoolStatus;
204
+ ticket_price: string;
205
+ currency: string;
206
+ max_tickets: number | null;
207
+ max_tickets_per_user: number | null;
208
+ total_entries: number;
209
+ total_pool_amount: string;
210
+ opens_at: string;
211
+ draws_at: string;
212
+ drawn_at: string | null;
213
+ winning_numbers: number[];
214
+ prize_tiers: PrizeTier[];
215
+ takeout_rate_bps: number;
216
+ }
217
+ interface LotteryEntry {
218
+ id: string;
219
+ pool_id: string;
220
+ user_id: string | null;
221
+ user_external_id: string | null;
222
+ ticket_number: number;
223
+ amount_paid: string;
224
+ currency: string;
225
+ status: LotteryEntryStatus;
226
+ prize_amount: string | null;
227
+ prize_tier: number | null;
228
+ purchased_at: string;
229
+ }
230
+ interface LotteryEntriesResponse {
231
+ entries: LotteryEntry[];
232
+ total: number;
233
+ }
234
+ interface BuyTicketParams {
235
+ /** Puul user UUID (provide userId or userExternalId) */
236
+ userId?: string;
237
+ /** Unique key to prevent duplicate purchases */
238
+ idempotencyKey: string;
239
+ /** Number of tickets (default: 1) */
240
+ quantity?: number;
241
+ /** Your linked external user ID (provide userId or userExternalId) */
242
+ userExternalId?: string;
243
+ }
244
+ interface BuyTicketResponse {
245
+ entries: LotteryEntry[];
246
+ }
247
+ interface LotteryDrawResult {
248
+ pool_id: string;
249
+ status: string;
250
+ drawn_at: string | null;
251
+ winning_numbers: number[];
252
+ total_pool_amount: string;
253
+ your_entries: Array<{
254
+ id: string;
255
+ ticket_number: number;
256
+ user_id: string | null;
257
+ user_external_id: string | null;
258
+ status: string;
259
+ prize_amount: string | null;
260
+ prize_tier: number | null;
261
+ }>;
262
+ your_winners: number;
263
+ your_total_winnings: number;
264
+ }
265
+ type WebhookEventType = 'user.created' | 'prediction.placed' | 'prediction.settled' | 'prediction.voided' | 'market.closed' | 'market.settled' | 'deposit.confirmed' | 'withdrawal.completed' | 'withdrawal.failed' | 'lottery.pool.drawn' | 'lottery.ticket.won';
176
266
  interface WebhookEvent<T = unknown> {
177
267
  event: WebhookEventType;
178
268
  timestamp: string;
@@ -284,6 +374,30 @@ interface WithdrawalFailedData {
284
374
  reason: string;
285
375
  failed_at: string;
286
376
  }
377
+ interface LotteryPoolDrawnData {
378
+ pool_id: string;
379
+ pool_title: string;
380
+ drawn_at: string;
381
+ winning_numbers: number[];
382
+ total_pool_amount: number;
383
+ total_entries: number;
384
+ takeout_amount: number;
385
+ total_payout: number;
386
+ your_entries: number;
387
+ your_winners: number;
388
+ your_total_winnings: number;
389
+ }
390
+ interface LotteryTicketWonData {
391
+ entry_id: string;
392
+ pool_id: string;
393
+ pool_title: string;
394
+ user_id: string;
395
+ user_external_id: string | null;
396
+ ticket_number: number;
397
+ prize_amount: number;
398
+ prize_tier: number;
399
+ drawn_at: string;
400
+ }
287
401
  interface PuulApiError {
288
402
  statusCode: number;
289
403
  message: string | string[];
@@ -335,6 +449,7 @@ declare class PuulPartner {
335
449
  readonly markets: MarketsAPI;
336
450
  readonly predictions: PredictionsAPI;
337
451
  readonly wallet: WalletAPI;
452
+ readonly lottery: LotteryAPI;
338
453
  constructor(config: PuulPartnerConfig);
339
454
  /** Get a valid access token, refreshing if needed */
340
455
  getAccessToken(): Promise<string>;
@@ -370,6 +485,8 @@ declare class PredictionsAPI {
370
485
  list(options?: {
371
486
  status?: PredictionStatus;
372
487
  limit?: number;
488
+ userId?: string;
489
+ userExternalId?: string;
373
490
  }): Promise<PredictionListResponse>;
374
491
  /** Create a pending prediction (JIT funding flow) */
375
492
  createPending(params: CreatePendingPredictionParams): Promise<PendingPrediction>;
@@ -404,6 +521,41 @@ declare class WalletAPI {
404
521
  */
405
522
  withdraw(params: WithdrawParams): Promise<WithdrawResult>;
406
523
  }
524
+ declare class LotteryAPI {
525
+ private readonly client;
526
+ constructor(client: PuulPartner);
527
+ /** List lottery pools, optionally filtered by status and frequency */
528
+ listPools(options?: {
529
+ status?: LotteryPoolStatus;
530
+ frequency?: string;
531
+ limit?: number;
532
+ }): Promise<LotteryPool[]>;
533
+ /** Get a specific pool by ID */
534
+ getPool(poolId: string): Promise<LotteryPool>;
535
+ /**
536
+ * Buy ticket(s) for a linked user.
537
+ *
538
+ * @example
539
+ * ```typescript
540
+ * const result = await puul.lottery.buyTicket('pool-uuid', {
541
+ * userId: 'puul-user-uuid',
542
+ * idempotencyKey: 'lottery-user456-pool1-001',
543
+ * quantity: 3,
544
+ * });
545
+ * ```
546
+ */
547
+ buyTicket(poolId: string, params: BuyTicketParams): Promise<BuyTicketResponse>;
548
+ /** List lottery entries for your partner account */
549
+ listEntries(options?: {
550
+ poolId?: string;
551
+ status?: LotteryEntryStatus;
552
+ limit?: number;
553
+ }): Promise<LotteryEntriesResponse>;
554
+ /** Get a single lottery entry by ID */
555
+ getEntry(entryId: string): Promise<LotteryEntry>;
556
+ /** Get draw results for a completed pool */
557
+ getDrawResults(poolId: string): Promise<LotteryDrawResult>;
558
+ }
407
559
 
408
560
  /**
409
561
  * Verify a webhook signature from Puul.
@@ -469,6 +621,10 @@ declare function isDepositConfirmedEvent(event: WebhookEvent): event is WebhookE
469
621
  declare function isWithdrawalCompletedEvent(event: WebhookEvent): event is WebhookEvent<WithdrawalCompletedData>;
470
622
  /** Type guard for withdrawal.failed events. */
471
623
  declare function isWithdrawalFailedEvent(event: WebhookEvent): event is WebhookEvent<WithdrawalFailedData>;
624
+ /** Type guard for lottery.pool.drawn events. */
625
+ declare function isLotteryPoolDrawnEvent(event: WebhookEvent): event is WebhookEvent<LotteryPoolDrawnData>;
626
+ /** Type guard for lottery.ticket.won events. */
627
+ declare function isLotteryTicketWonEvent(event: WebhookEvent): event is WebhookEvent<LotteryTicketWonData>;
472
628
  /**
473
629
  * Convenience cast for prediction.settled event data.
474
630
  * Call after verifying with `isPredictionSettledEvent`.
@@ -479,5 +635,15 @@ declare function asPredictionSettledData(event: WebhookEvent): PredictionSettled
479
635
  * Call after verifying with `isMarketSettledEvent`.
480
636
  */
481
637
  declare function asMarketSettledData(event: WebhookEvent): MarketSettledData;
638
+ /**
639
+ * Convenience cast for lottery.pool.drawn event data.
640
+ * Call after verifying with `isLotteryPoolDrawnEvent`.
641
+ */
642
+ declare function asLotteryPoolDrawnData(event: WebhookEvent): LotteryPoolDrawnData;
643
+ /**
644
+ * Convenience cast for lottery.ticket.won event data.
645
+ * Call after verifying with `isLotteryTicketWonEvent`.
646
+ */
647
+ declare function asLotteryTicketWonData(event: WebhookEvent): LotteryTicketWonData;
482
648
 
483
- export { type AccessTokenResponse, type CreateLinkTokenParams, type CreatePendingPredictionParams, type CreateQuoteParams, type Currency, type DepositAccountInfo, type DepositConfirmedData, type DepositParams, type LinkTokenResponse, type Market, type MarketClosedData, type MarketOutcome, type MarketSettledData, type PendingPrediction, type PlacePredictionParams, type Prediction, type PredictionListResponse, type PredictionPlacedData, type PredictionSettledData, type PredictionStatus, type PredictionVoidedData, type PuulApiError, PuulError, PuulPartner, type PuulPartnerConfig, type QuoteResponse, type SessionResponse, type UserCreatedData, type WalletBalance, type WebhookEvent, type WebhookEventType, type WithdrawMethod, type WithdrawParams, type WithdrawResult, type WithdrawalCompletedData, type WithdrawalFailedData, asMarketSettledData, asPredictionSettledData, isDepositConfirmedEvent, isMarketClosedEvent, isMarketSettledEvent, isPredictionPlacedEvent, isPredictionSettledEvent, isPredictionVoidedEvent, isWithdrawalCompletedEvent, isWithdrawalFailedEvent, parseWebhookEvent, verifyWebhookSignature };
649
+ export { type AccessTokenResponse, type BuyTicketParams, type BuyTicketResponse, type CreateLinkTokenParams, type CreatePendingPredictionParams, type CreateQuoteParams, type Currency, type DepositAccountInfo, type DepositConfirmedData, type DepositParams, type LinkTokenResponse, type LotteryDrawResult, type LotteryEntriesResponse, type LotteryEntry, type LotteryEntryStatus, type LotteryPool, type LotteryPoolDrawnData, type LotteryPoolFrequency, type LotteryPoolStatus, type LotteryPoolType, type LotteryTicketWonData, type Market, type MarketClosedData, type MarketOutcome, type MarketSettledData, type PendingPrediction, type PlacePredictionParams, type Prediction, type PredictionListResponse, type PredictionPlacedData, type PredictionSettledData, type PredictionStatus, type PredictionVoidedData, type PrizeTier, type PuulApiError, PuulError, PuulPartner, type PuulPartnerConfig, type QuoteResponse, type SessionResponse, type UserCreatedData, type WalletBalance, type WebhookEvent, type WebhookEventType, type WithdrawMethod, type WithdrawParams, type WithdrawResult, type WithdrawalCompletedData, type WithdrawalFailedData, asLotteryPoolDrawnData, asLotteryTicketWonData, asMarketSettledData, asPredictionSettledData, isDepositConfirmedEvent, isLotteryPoolDrawnEvent, isLotteryTicketWonEvent, isMarketClosedEvent, isMarketSettledEvent, isPredictionPlacedEvent, isPredictionSettledEvent, isPredictionVoidedEvent, isWithdrawalCompletedEvent, isWithdrawalFailedEvent, parseWebhookEvent, verifyWebhookSignature };
package/dist/index.d.ts CHANGED
@@ -63,6 +63,10 @@ interface PlacePredictionParams {
63
63
  stakeAmount: number;
64
64
  stakeCurrency: Currency;
65
65
  idempotencyKey: string;
66
+ /** Linked Puul user UUID (provide userId or userExternalId) */
67
+ userId?: string;
68
+ /** Your linked external user ID (provide userId or userExternalId) */
69
+ userExternalId?: string;
66
70
  /** Optional quote ID for slippage protection */
67
71
  quoteId?: string;
68
72
  /** Optional FX quote ID */
@@ -75,6 +79,10 @@ interface CreateQuoteParams {
75
79
  outcomeId: string;
76
80
  stakeAmount: number;
77
81
  stakeCurrency: Currency;
82
+ /** Linked Puul user UUID (provide userId or userExternalId) */
83
+ userId?: string;
84
+ /** Your linked external user ID (provide userId or userExternalId) */
85
+ userExternalId?: string;
78
86
  }
79
87
  interface QuoteResponse {
80
88
  quoteId: string;
@@ -153,6 +161,10 @@ interface DepositParams {
153
161
  currency?: string;
154
162
  idempotency_key: string;
155
163
  reference?: string;
164
+ /** Linked Puul user UUID (provide userId or userExternalId) */
165
+ userId?: string;
166
+ /** Your linked external user ID (provide userId or userExternalId) */
167
+ userExternalId?: string;
156
168
  }
157
169
  type WithdrawMethod = 'bank' | 'crypto';
158
170
  interface WithdrawParams {
@@ -172,7 +184,85 @@ interface WithdrawResult {
172
184
  payoutReference: string | null;
173
185
  status: string;
174
186
  }
175
- type WebhookEventType = 'user.created' | 'prediction.placed' | 'prediction.settled' | 'prediction.voided' | 'market.closed' | 'market.settled' | 'deposit.confirmed' | 'withdrawal.completed' | 'withdrawal.failed';
187
+ type LotteryPoolType = 'winner_takes_all' | 'tiered';
188
+ type LotteryPoolFrequency = 'daily' | 'weekly' | 'monthly' | 'quarterly';
189
+ type LotteryPoolStatus = 'upcoming' | 'open' | 'drawing' | 'settled' | 'cancelled';
190
+ type LotteryEntryStatus = 'active' | 'won' | 'lost' | 'refunded';
191
+ interface PrizeTier {
192
+ /** 1-based rank (1 = first place) */
193
+ rank: number;
194
+ /** Percentage of distributable pool in basis points (5000 = 50%) */
195
+ pct: number;
196
+ }
197
+ interface LotteryPool {
198
+ id: string;
199
+ title: string;
200
+ description: string | null;
201
+ type: LotteryPoolType;
202
+ frequency: LotteryPoolFrequency;
203
+ status: LotteryPoolStatus;
204
+ ticket_price: string;
205
+ currency: string;
206
+ max_tickets: number | null;
207
+ max_tickets_per_user: number | null;
208
+ total_entries: number;
209
+ total_pool_amount: string;
210
+ opens_at: string;
211
+ draws_at: string;
212
+ drawn_at: string | null;
213
+ winning_numbers: number[];
214
+ prize_tiers: PrizeTier[];
215
+ takeout_rate_bps: number;
216
+ }
217
+ interface LotteryEntry {
218
+ id: string;
219
+ pool_id: string;
220
+ user_id: string | null;
221
+ user_external_id: string | null;
222
+ ticket_number: number;
223
+ amount_paid: string;
224
+ currency: string;
225
+ status: LotteryEntryStatus;
226
+ prize_amount: string | null;
227
+ prize_tier: number | null;
228
+ purchased_at: string;
229
+ }
230
+ interface LotteryEntriesResponse {
231
+ entries: LotteryEntry[];
232
+ total: number;
233
+ }
234
+ interface BuyTicketParams {
235
+ /** Puul user UUID (provide userId or userExternalId) */
236
+ userId?: string;
237
+ /** Unique key to prevent duplicate purchases */
238
+ idempotencyKey: string;
239
+ /** Number of tickets (default: 1) */
240
+ quantity?: number;
241
+ /** Your linked external user ID (provide userId or userExternalId) */
242
+ userExternalId?: string;
243
+ }
244
+ interface BuyTicketResponse {
245
+ entries: LotteryEntry[];
246
+ }
247
+ interface LotteryDrawResult {
248
+ pool_id: string;
249
+ status: string;
250
+ drawn_at: string | null;
251
+ winning_numbers: number[];
252
+ total_pool_amount: string;
253
+ your_entries: Array<{
254
+ id: string;
255
+ ticket_number: number;
256
+ user_id: string | null;
257
+ user_external_id: string | null;
258
+ status: string;
259
+ prize_amount: string | null;
260
+ prize_tier: number | null;
261
+ }>;
262
+ your_winners: number;
263
+ your_total_winnings: number;
264
+ }
265
+ type WebhookEventType = 'user.created' | 'prediction.placed' | 'prediction.settled' | 'prediction.voided' | 'market.closed' | 'market.settled' | 'deposit.confirmed' | 'withdrawal.completed' | 'withdrawal.failed' | 'lottery.pool.drawn' | 'lottery.ticket.won';
176
266
  interface WebhookEvent<T = unknown> {
177
267
  event: WebhookEventType;
178
268
  timestamp: string;
@@ -284,6 +374,30 @@ interface WithdrawalFailedData {
284
374
  reason: string;
285
375
  failed_at: string;
286
376
  }
377
+ interface LotteryPoolDrawnData {
378
+ pool_id: string;
379
+ pool_title: string;
380
+ drawn_at: string;
381
+ winning_numbers: number[];
382
+ total_pool_amount: number;
383
+ total_entries: number;
384
+ takeout_amount: number;
385
+ total_payout: number;
386
+ your_entries: number;
387
+ your_winners: number;
388
+ your_total_winnings: number;
389
+ }
390
+ interface LotteryTicketWonData {
391
+ entry_id: string;
392
+ pool_id: string;
393
+ pool_title: string;
394
+ user_id: string;
395
+ user_external_id: string | null;
396
+ ticket_number: number;
397
+ prize_amount: number;
398
+ prize_tier: number;
399
+ drawn_at: string;
400
+ }
287
401
  interface PuulApiError {
288
402
  statusCode: number;
289
403
  message: string | string[];
@@ -335,6 +449,7 @@ declare class PuulPartner {
335
449
  readonly markets: MarketsAPI;
336
450
  readonly predictions: PredictionsAPI;
337
451
  readonly wallet: WalletAPI;
452
+ readonly lottery: LotteryAPI;
338
453
  constructor(config: PuulPartnerConfig);
339
454
  /** Get a valid access token, refreshing if needed */
340
455
  getAccessToken(): Promise<string>;
@@ -370,6 +485,8 @@ declare class PredictionsAPI {
370
485
  list(options?: {
371
486
  status?: PredictionStatus;
372
487
  limit?: number;
488
+ userId?: string;
489
+ userExternalId?: string;
373
490
  }): Promise<PredictionListResponse>;
374
491
  /** Create a pending prediction (JIT funding flow) */
375
492
  createPending(params: CreatePendingPredictionParams): Promise<PendingPrediction>;
@@ -404,6 +521,41 @@ declare class WalletAPI {
404
521
  */
405
522
  withdraw(params: WithdrawParams): Promise<WithdrawResult>;
406
523
  }
524
+ declare class LotteryAPI {
525
+ private readonly client;
526
+ constructor(client: PuulPartner);
527
+ /** List lottery pools, optionally filtered by status and frequency */
528
+ listPools(options?: {
529
+ status?: LotteryPoolStatus;
530
+ frequency?: string;
531
+ limit?: number;
532
+ }): Promise<LotteryPool[]>;
533
+ /** Get a specific pool by ID */
534
+ getPool(poolId: string): Promise<LotteryPool>;
535
+ /**
536
+ * Buy ticket(s) for a linked user.
537
+ *
538
+ * @example
539
+ * ```typescript
540
+ * const result = await puul.lottery.buyTicket('pool-uuid', {
541
+ * userId: 'puul-user-uuid',
542
+ * idempotencyKey: 'lottery-user456-pool1-001',
543
+ * quantity: 3,
544
+ * });
545
+ * ```
546
+ */
547
+ buyTicket(poolId: string, params: BuyTicketParams): Promise<BuyTicketResponse>;
548
+ /** List lottery entries for your partner account */
549
+ listEntries(options?: {
550
+ poolId?: string;
551
+ status?: LotteryEntryStatus;
552
+ limit?: number;
553
+ }): Promise<LotteryEntriesResponse>;
554
+ /** Get a single lottery entry by ID */
555
+ getEntry(entryId: string): Promise<LotteryEntry>;
556
+ /** Get draw results for a completed pool */
557
+ getDrawResults(poolId: string): Promise<LotteryDrawResult>;
558
+ }
407
559
 
408
560
  /**
409
561
  * Verify a webhook signature from Puul.
@@ -469,6 +621,10 @@ declare function isDepositConfirmedEvent(event: WebhookEvent): event is WebhookE
469
621
  declare function isWithdrawalCompletedEvent(event: WebhookEvent): event is WebhookEvent<WithdrawalCompletedData>;
470
622
  /** Type guard for withdrawal.failed events. */
471
623
  declare function isWithdrawalFailedEvent(event: WebhookEvent): event is WebhookEvent<WithdrawalFailedData>;
624
+ /** Type guard for lottery.pool.drawn events. */
625
+ declare function isLotteryPoolDrawnEvent(event: WebhookEvent): event is WebhookEvent<LotteryPoolDrawnData>;
626
+ /** Type guard for lottery.ticket.won events. */
627
+ declare function isLotteryTicketWonEvent(event: WebhookEvent): event is WebhookEvent<LotteryTicketWonData>;
472
628
  /**
473
629
  * Convenience cast for prediction.settled event data.
474
630
  * Call after verifying with `isPredictionSettledEvent`.
@@ -479,5 +635,15 @@ declare function asPredictionSettledData(event: WebhookEvent): PredictionSettled
479
635
  * Call after verifying with `isMarketSettledEvent`.
480
636
  */
481
637
  declare function asMarketSettledData(event: WebhookEvent): MarketSettledData;
638
+ /**
639
+ * Convenience cast for lottery.pool.drawn event data.
640
+ * Call after verifying with `isLotteryPoolDrawnEvent`.
641
+ */
642
+ declare function asLotteryPoolDrawnData(event: WebhookEvent): LotteryPoolDrawnData;
643
+ /**
644
+ * Convenience cast for lottery.ticket.won event data.
645
+ * Call after verifying with `isLotteryTicketWonEvent`.
646
+ */
647
+ declare function asLotteryTicketWonData(event: WebhookEvent): LotteryTicketWonData;
482
648
 
483
- export { type AccessTokenResponse, type CreateLinkTokenParams, type CreatePendingPredictionParams, type CreateQuoteParams, type Currency, type DepositAccountInfo, type DepositConfirmedData, type DepositParams, type LinkTokenResponse, type Market, type MarketClosedData, type MarketOutcome, type MarketSettledData, type PendingPrediction, type PlacePredictionParams, type Prediction, type PredictionListResponse, type PredictionPlacedData, type PredictionSettledData, type PredictionStatus, type PredictionVoidedData, type PuulApiError, PuulError, PuulPartner, type PuulPartnerConfig, type QuoteResponse, type SessionResponse, type UserCreatedData, type WalletBalance, type WebhookEvent, type WebhookEventType, type WithdrawMethod, type WithdrawParams, type WithdrawResult, type WithdrawalCompletedData, type WithdrawalFailedData, asMarketSettledData, asPredictionSettledData, isDepositConfirmedEvent, isMarketClosedEvent, isMarketSettledEvent, isPredictionPlacedEvent, isPredictionSettledEvent, isPredictionVoidedEvent, isWithdrawalCompletedEvent, isWithdrawalFailedEvent, parseWebhookEvent, verifyWebhookSignature };
649
+ export { type AccessTokenResponse, type BuyTicketParams, type BuyTicketResponse, type CreateLinkTokenParams, type CreatePendingPredictionParams, type CreateQuoteParams, type Currency, type DepositAccountInfo, type DepositConfirmedData, type DepositParams, type LinkTokenResponse, type LotteryDrawResult, type LotteryEntriesResponse, type LotteryEntry, type LotteryEntryStatus, type LotteryPool, type LotteryPoolDrawnData, type LotteryPoolFrequency, type LotteryPoolStatus, type LotteryPoolType, type LotteryTicketWonData, type Market, type MarketClosedData, type MarketOutcome, type MarketSettledData, type PendingPrediction, type PlacePredictionParams, type Prediction, type PredictionListResponse, type PredictionPlacedData, type PredictionSettledData, type PredictionStatus, type PredictionVoidedData, type PrizeTier, type PuulApiError, PuulError, PuulPartner, type PuulPartnerConfig, type QuoteResponse, type SessionResponse, type UserCreatedData, type WalletBalance, type WebhookEvent, type WebhookEventType, type WithdrawMethod, type WithdrawParams, type WithdrawResult, type WithdrawalCompletedData, type WithdrawalFailedData, asLotteryPoolDrawnData, asLotteryTicketWonData, asMarketSettledData, asPredictionSettledData, isDepositConfirmedEvent, isLotteryPoolDrawnEvent, isLotteryTicketWonEvent, isMarketClosedEvent, isMarketSettledEvent, isPredictionPlacedEvent, isPredictionSettledEvent, isPredictionVoidedEvent, isWithdrawalCompletedEvent, isWithdrawalFailedEvent, parseWebhookEvent, verifyWebhookSignature };
package/dist/index.js CHANGED
@@ -22,9 +22,13 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  PuulError: () => PuulError,
24
24
  PuulPartner: () => PuulPartner,
25
+ asLotteryPoolDrawnData: () => asLotteryPoolDrawnData,
26
+ asLotteryTicketWonData: () => asLotteryTicketWonData,
25
27
  asMarketSettledData: () => asMarketSettledData,
26
28
  asPredictionSettledData: () => asPredictionSettledData,
27
29
  isDepositConfirmedEvent: () => isDepositConfirmedEvent,
30
+ isLotteryPoolDrawnEvent: () => isLotteryPoolDrawnEvent,
31
+ isLotteryTicketWonEvent: () => isLotteryTicketWonEvent,
28
32
  isMarketClosedEvent: () => isMarketClosedEvent,
29
33
  isMarketSettledEvent: () => isMarketSettledEvent,
30
34
  isPredictionPlacedEvent: () => isPredictionPlacedEvent,
@@ -67,6 +71,7 @@ var PuulPartner = class {
67
71
  this.markets = new MarketsAPI(this);
68
72
  this.predictions = new PredictionsAPI(this);
69
73
  this.wallet = new WalletAPI(this);
74
+ this.lottery = new LotteryAPI(this);
70
75
  }
71
76
  // ==========================================================
72
77
  // Internal HTTP layer
@@ -185,11 +190,21 @@ var PredictionsAPI = class {
185
190
  }
186
191
  /** Create a binding quote for slippage protection (expires in 10s) */
187
192
  async createQuote(params) {
188
- return this.client.request("POST", "/partner/predictions/quote", params);
193
+ const { userId, userExternalId, ...rest } = params;
194
+ return this.client.request("POST", "/partner/predictions/quote", {
195
+ ...rest,
196
+ user_id: userId,
197
+ user_external_id: userExternalId
198
+ });
189
199
  }
190
200
  /** Place a prediction on a market outcome */
191
201
  async place(params) {
192
- return this.client.request("POST", "/partner/predictions", params);
202
+ const { userId, userExternalId, ...rest } = params;
203
+ return this.client.request("POST", "/partner/predictions", {
204
+ ...rest,
205
+ user_id: userId,
206
+ user_external_id: userExternalId
207
+ });
193
208
  }
194
209
  /** Get a specific prediction by ID */
195
210
  async get(predictionId) {
@@ -200,6 +215,8 @@ var PredictionsAPI = class {
200
215
  const params = new URLSearchParams();
201
216
  if (options?.status) params.set("status", options.status);
202
217
  if (options?.limit) params.set("limit", String(options.limit));
218
+ if (options?.userId) params.set("user_id", options.userId);
219
+ if (options?.userExternalId) params.set("user_external_id", options.userExternalId);
203
220
  const query = params.toString() ? `?${params.toString()}` : "";
204
221
  return this.client.request("GET", `/partner/predictions${query}`);
205
222
  }
@@ -231,7 +248,12 @@ var WalletAPI = class {
231
248
  }
232
249
  /** Deposit funds to a linked user wallet */
233
250
  async deposit(params) {
234
- return this.client.request("POST", "/partner/wallet/deposit", params);
251
+ const { userId, userExternalId, ...rest } = params;
252
+ return this.client.request("POST", "/partner/wallet/deposit", {
253
+ ...rest,
254
+ user_id: userId,
255
+ user_external_id: userExternalId
256
+ });
235
257
  }
236
258
  /** Get withdrawal fee estimate */
237
259
  async getWithdrawalFees(currency, amount) {
@@ -254,21 +276,76 @@ var WalletAPI = class {
254
276
  return this.client.request("POST", "/partner/wallet/withdraw", params);
255
277
  }
256
278
  };
279
+ var LotteryAPI = class {
280
+ constructor(client) {
281
+ this.client = client;
282
+ }
283
+ /** List lottery pools, optionally filtered by status and frequency */
284
+ async listPools(options) {
285
+ const params = new URLSearchParams();
286
+ if (options?.status) params.set("status", options.status);
287
+ if (options?.frequency) params.set("frequency", options.frequency);
288
+ if (options?.limit) params.set("limit", String(options.limit));
289
+ const query = params.toString() ? `?${params.toString()}` : "";
290
+ return this.client.request("GET", `/partner/lottery/pools${query}`);
291
+ }
292
+ /** Get a specific pool by ID */
293
+ async getPool(poolId) {
294
+ return this.client.request("GET", `/partner/lottery/pools/${poolId}`);
295
+ }
296
+ /**
297
+ * Buy ticket(s) for a linked user.
298
+ *
299
+ * @example
300
+ * ```typescript
301
+ * const result = await puul.lottery.buyTicket('pool-uuid', {
302
+ * userId: 'puul-user-uuid',
303
+ * idempotencyKey: 'lottery-user456-pool1-001',
304
+ * quantity: 3,
305
+ * });
306
+ * ```
307
+ */
308
+ async buyTicket(poolId, params) {
309
+ return this.client.request("POST", `/partner/lottery/pools/${poolId}/buy`, {
310
+ user_id: params.userId,
311
+ idempotency_key: params.idempotencyKey,
312
+ quantity: params.quantity,
313
+ user_external_id: params.userExternalId
314
+ });
315
+ }
316
+ /** List lottery entries for your partner account */
317
+ async listEntries(options) {
318
+ const params = new URLSearchParams();
319
+ if (options?.poolId) params.set("pool_id", options.poolId);
320
+ if (options?.status) params.set("status", options.status);
321
+ if (options?.limit) params.set("limit", String(options.limit));
322
+ const query = params.toString() ? `?${params.toString()}` : "";
323
+ return this.client.request("GET", `/partner/lottery/entries${query}`);
324
+ }
325
+ /** Get a single lottery entry by ID */
326
+ async getEntry(entryId) {
327
+ return this.client.request("GET", `/partner/lottery/entries/${entryId}`);
328
+ }
329
+ /** Get draw results for a completed pool */
330
+ async getDrawResults(poolId) {
331
+ return this.client.request("GET", `/partner/lottery/pools/${poolId}/results`);
332
+ }
333
+ };
257
334
 
258
335
  // src/webhooks.ts
259
- var import_crypto = require("crypto");
336
+ var import_node_crypto = require("crypto");
260
337
  function verifyWebhookSignature(payload, signature, secret) {
261
338
  if (!payload || !signature || !secret) {
262
339
  return false;
263
340
  }
264
- const expectedSignature = (0, import_crypto.createHmac)("sha256", secret).update(payload).digest("hex");
341
+ const expectedSignature = (0, import_node_crypto.createHmac)("sha256", secret).update(payload).digest("hex");
265
342
  try {
266
343
  const sigBuffer = Buffer.from(signature, "hex");
267
344
  const expectedBuffer = Buffer.from(expectedSignature, "hex");
268
345
  if (sigBuffer.length !== expectedBuffer.length) {
269
346
  return false;
270
347
  }
271
- return (0, import_crypto.timingSafeEqual)(sigBuffer, expectedBuffer);
348
+ return (0, import_node_crypto.timingSafeEqual)(sigBuffer, expectedBuffer);
272
349
  } catch {
273
350
  return false;
274
351
  }
@@ -279,7 +356,7 @@ function parseWebhookEvent(body) {
279
356
  }
280
357
  const event = body;
281
358
  if (typeof event.event !== "string") {
282
- throw new Error('Invalid webhook body: missing "event" field');
359
+ throw new TypeError('Invalid webhook body: missing "event" field');
283
360
  }
284
361
  return {
285
362
  event: event.event,
@@ -311,19 +388,35 @@ function isWithdrawalCompletedEvent(event) {
311
388
  function isWithdrawalFailedEvent(event) {
312
389
  return event.event === "withdrawal.failed";
313
390
  }
391
+ function isLotteryPoolDrawnEvent(event) {
392
+ return event.event === "lottery.pool.drawn";
393
+ }
394
+ function isLotteryTicketWonEvent(event) {
395
+ return event.event === "lottery.ticket.won";
396
+ }
314
397
  function asPredictionSettledData(event) {
315
398
  return event.data;
316
399
  }
317
400
  function asMarketSettledData(event) {
318
401
  return event.data;
319
402
  }
403
+ function asLotteryPoolDrawnData(event) {
404
+ return event.data;
405
+ }
406
+ function asLotteryTicketWonData(event) {
407
+ return event.data;
408
+ }
320
409
  // Annotate the CommonJS export names for ESM import in node:
321
410
  0 && (module.exports = {
322
411
  PuulError,
323
412
  PuulPartner,
413
+ asLotteryPoolDrawnData,
414
+ asLotteryTicketWonData,
324
415
  asMarketSettledData,
325
416
  asPredictionSettledData,
326
417
  isDepositConfirmedEvent,
418
+ isLotteryPoolDrawnEvent,
419
+ isLotteryTicketWonEvent,
327
420
  isMarketClosedEvent,
328
421
  isMarketSettledEvent,
329
422
  isPredictionPlacedEvent,
package/dist/index.mjs CHANGED
@@ -28,6 +28,7 @@ var PuulPartner = class {
28
28
  this.markets = new MarketsAPI(this);
29
29
  this.predictions = new PredictionsAPI(this);
30
30
  this.wallet = new WalletAPI(this);
31
+ this.lottery = new LotteryAPI(this);
31
32
  }
32
33
  // ==========================================================
33
34
  // Internal HTTP layer
@@ -146,11 +147,21 @@ var PredictionsAPI = class {
146
147
  }
147
148
  /** Create a binding quote for slippage protection (expires in 10s) */
148
149
  async createQuote(params) {
149
- return this.client.request("POST", "/partner/predictions/quote", params);
150
+ const { userId, userExternalId, ...rest } = params;
151
+ return this.client.request("POST", "/partner/predictions/quote", {
152
+ ...rest,
153
+ user_id: userId,
154
+ user_external_id: userExternalId
155
+ });
150
156
  }
151
157
  /** Place a prediction on a market outcome */
152
158
  async place(params) {
153
- return this.client.request("POST", "/partner/predictions", params);
159
+ const { userId, userExternalId, ...rest } = params;
160
+ return this.client.request("POST", "/partner/predictions", {
161
+ ...rest,
162
+ user_id: userId,
163
+ user_external_id: userExternalId
164
+ });
154
165
  }
155
166
  /** Get a specific prediction by ID */
156
167
  async get(predictionId) {
@@ -161,6 +172,8 @@ var PredictionsAPI = class {
161
172
  const params = new URLSearchParams();
162
173
  if (options?.status) params.set("status", options.status);
163
174
  if (options?.limit) params.set("limit", String(options.limit));
175
+ if (options?.userId) params.set("user_id", options.userId);
176
+ if (options?.userExternalId) params.set("user_external_id", options.userExternalId);
164
177
  const query = params.toString() ? `?${params.toString()}` : "";
165
178
  return this.client.request("GET", `/partner/predictions${query}`);
166
179
  }
@@ -192,7 +205,12 @@ var WalletAPI = class {
192
205
  }
193
206
  /** Deposit funds to a linked user wallet */
194
207
  async deposit(params) {
195
- return this.client.request("POST", "/partner/wallet/deposit", params);
208
+ const { userId, userExternalId, ...rest } = params;
209
+ return this.client.request("POST", "/partner/wallet/deposit", {
210
+ ...rest,
211
+ user_id: userId,
212
+ user_external_id: userExternalId
213
+ });
196
214
  }
197
215
  /** Get withdrawal fee estimate */
198
216
  async getWithdrawalFees(currency, amount) {
@@ -215,6 +233,61 @@ var WalletAPI = class {
215
233
  return this.client.request("POST", "/partner/wallet/withdraw", params);
216
234
  }
217
235
  };
236
+ var LotteryAPI = class {
237
+ constructor(client) {
238
+ this.client = client;
239
+ }
240
+ /** List lottery pools, optionally filtered by status and frequency */
241
+ async listPools(options) {
242
+ const params = new URLSearchParams();
243
+ if (options?.status) params.set("status", options.status);
244
+ if (options?.frequency) params.set("frequency", options.frequency);
245
+ if (options?.limit) params.set("limit", String(options.limit));
246
+ const query = params.toString() ? `?${params.toString()}` : "";
247
+ return this.client.request("GET", `/partner/lottery/pools${query}`);
248
+ }
249
+ /** Get a specific pool by ID */
250
+ async getPool(poolId) {
251
+ return this.client.request("GET", `/partner/lottery/pools/${poolId}`);
252
+ }
253
+ /**
254
+ * Buy ticket(s) for a linked user.
255
+ *
256
+ * @example
257
+ * ```typescript
258
+ * const result = await puul.lottery.buyTicket('pool-uuid', {
259
+ * userId: 'puul-user-uuid',
260
+ * idempotencyKey: 'lottery-user456-pool1-001',
261
+ * quantity: 3,
262
+ * });
263
+ * ```
264
+ */
265
+ async buyTicket(poolId, params) {
266
+ return this.client.request("POST", `/partner/lottery/pools/${poolId}/buy`, {
267
+ user_id: params.userId,
268
+ idempotency_key: params.idempotencyKey,
269
+ quantity: params.quantity,
270
+ user_external_id: params.userExternalId
271
+ });
272
+ }
273
+ /** List lottery entries for your partner account */
274
+ async listEntries(options) {
275
+ const params = new URLSearchParams();
276
+ if (options?.poolId) params.set("pool_id", options.poolId);
277
+ if (options?.status) params.set("status", options.status);
278
+ if (options?.limit) params.set("limit", String(options.limit));
279
+ const query = params.toString() ? `?${params.toString()}` : "";
280
+ return this.client.request("GET", `/partner/lottery/entries${query}`);
281
+ }
282
+ /** Get a single lottery entry by ID */
283
+ async getEntry(entryId) {
284
+ return this.client.request("GET", `/partner/lottery/entries/${entryId}`);
285
+ }
286
+ /** Get draw results for a completed pool */
287
+ async getDrawResults(poolId) {
288
+ return this.client.request("GET", `/partner/lottery/pools/${poolId}/results`);
289
+ }
290
+ };
218
291
 
219
292
  // src/webhooks.ts
220
293
  import { createHmac, timingSafeEqual } from "crypto";
@@ -240,7 +313,7 @@ function parseWebhookEvent(body) {
240
313
  }
241
314
  const event = body;
242
315
  if (typeof event.event !== "string") {
243
- throw new Error('Invalid webhook body: missing "event" field');
316
+ throw new TypeError('Invalid webhook body: missing "event" field');
244
317
  }
245
318
  return {
246
319
  event: event.event,
@@ -272,18 +345,34 @@ function isWithdrawalCompletedEvent(event) {
272
345
  function isWithdrawalFailedEvent(event) {
273
346
  return event.event === "withdrawal.failed";
274
347
  }
348
+ function isLotteryPoolDrawnEvent(event) {
349
+ return event.event === "lottery.pool.drawn";
350
+ }
351
+ function isLotteryTicketWonEvent(event) {
352
+ return event.event === "lottery.ticket.won";
353
+ }
275
354
  function asPredictionSettledData(event) {
276
355
  return event.data;
277
356
  }
278
357
  function asMarketSettledData(event) {
279
358
  return event.data;
280
359
  }
360
+ function asLotteryPoolDrawnData(event) {
361
+ return event.data;
362
+ }
363
+ function asLotteryTicketWonData(event) {
364
+ return event.data;
365
+ }
281
366
  export {
282
367
  PuulError,
283
368
  PuulPartner,
369
+ asLotteryPoolDrawnData,
370
+ asLotteryTicketWonData,
284
371
  asMarketSettledData,
285
372
  asPredictionSettledData,
286
373
  isDepositConfirmedEvent,
374
+ isLotteryPoolDrawnEvent,
375
+ isLotteryTicketWonEvent,
287
376
  isMarketClosedEvent,
288
377
  isMarketSettledEvent,
289
378
  isPredictionPlacedEvent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@puul/partner-sdk",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Official TypeScript SDK for the Puul Partner API — integrate prediction markets into your platform",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -42,4 +42,4 @@
42
42
  "engines": {
43
43
  "node": ">=18.0.0"
44
44
  }
45
- }
45
+ }