dgc-core 2.0.7 → 2.0.9
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 +21 -0
- package/dist/giveaways/giveaway-repository.d.ts +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/pub.js +3 -2
- package/dist/task.js +10 -3
- package/dist/types/api.d.ts +186 -0
- package/dist/types/pricecharting.d.ts +2 -17
- package/package.json +1 -1
- package/dist/tw/utils.d.ts +0 -1
- package/dist/tw/utils.js +0 -19
- package/dist/tw/wallet.d.ts +0 -1
- package/dist/tw/wallet.js +0 -57
package/README.md
CHANGED
|
@@ -97,3 +97,24 @@ The shared RevenueCat catalog maps Rookie, Collector and Elite entitlement IDs f
|
|
|
97
97
|
`createRevenueCatClient` accepts server-provided credentials and request limits. `verifyCreditGiveawayEntitlement` checks all eligible tiers using one paginated customer lookup. Null expiry represents non-expiring access; expired entitlements are excluded. Network, rate-limit and malformed-response failures throw a sanitized 503 without exposing credentials. The active entitlements endpoint has no environment filter; configure RevenueCat Sandbox Testing Access and test-account policy for the selected project.
|
|
98
98
|
|
|
99
99
|
Credit winner selection, confirmation and replacement require an injected `checkCreditEligibility(userId)` callback in the optional third `GiveawayRepository` constructor argument. Missing verification is a 503, never a fallback to saved membership. Product operations do not call the verifier. Checks occur outside transactions; reviewed revisions, candidate identity and unexpired evidence are validated at commit. Random selection picks one candidate first, then checks their entitlement. Inactive candidates are retried without replacement up to `creditWinnerMaxAttempts` (default 5; integer 1-100). It never checks the whole entrant pool in advance. The 30-second draw budget remains in place. Transient RevenueCat network/429/5xx failures retry the same user and page up to three attempts with bounded backoff and Retry-After handling, sharing the existing total lookup deadline. Authorization, missing-resource and malformed-response failures are not retried or treated as inactive access. Evidence is stored on selections and winners. Existing confirmed claims and idempotent rewards do not recheck access.
|
|
100
|
+
|
|
101
|
+
## Public mobile API contracts
|
|
102
|
+
|
|
103
|
+
PriceChartingApiCard and PriceChartingVariantApiCard are defined in src/types/api.ts and remain available through dgc-core/types.
|
|
104
|
+
|
|
105
|
+
The browser-safe types entry exports the public card, set, pricing, image-search,
|
|
106
|
+
population and grading-response contracts from src/types/api.ts. They reuse
|
|
107
|
+
the existing response envelopes and PriceCharting types while keeping nullable
|
|
108
|
+
image-search fields separate from catalog cards. ApiCardResponse, ApiCardsResponse,
|
|
109
|
+
ApiMarketHistoryResponse and the other response aliases model the actual HTTP
|
|
110
|
+
envelopes without exposing stored database records.
|
|
111
|
+
|
|
112
|
+
The dgc-web documentation generator reads these TypeScript contracts and preserves
|
|
113
|
+
its client-facing descriptions as separate annotations. Change shared model fields
|
|
114
|
+
here, then sync the dashboard's generated documentation. The package export tests
|
|
115
|
+
and mobile API compile tests verify public availability, nullability, literal
|
|
116
|
+
statuses and the browser import boundary.
|
|
117
|
+
|
|
118
|
+
These additions follow the existing package release process. Publish a new core
|
|
119
|
+
version before registry consumers import the new aliases; documentation can be
|
|
120
|
+
generated from the reviewed local checkout before that release.
|
|
@@ -61,9 +61,9 @@ export declare class GiveawayRepository {
|
|
|
61
61
|
private advanceGiveaway;
|
|
62
62
|
submitEntry(account: UserProfile, id: string, raw: unknown): Promise<{
|
|
63
63
|
_id: string;
|
|
64
|
+
name: string;
|
|
64
65
|
email: string;
|
|
65
66
|
_collectorType: UserCollectorType | null;
|
|
66
|
-
name: string;
|
|
67
67
|
giveawayId: import("../types").GiveawayObjectId;
|
|
68
68
|
country?: string | undefined;
|
|
69
69
|
enteredAt: string;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -18,8 +18,6 @@ __exportStar(require("./types"), exports);
|
|
|
18
18
|
__exportStar(require("./db/mongo"), exports);
|
|
19
19
|
__exportStar(require("./db/mongo2"), exports);
|
|
20
20
|
__exportStar(require("./db/mongo3"), exports);
|
|
21
|
-
__exportStar(require("./tw/utils"), exports);
|
|
22
|
-
__exportStar(require("./tw/wallet"), exports);
|
|
23
21
|
__exportStar(require("./auth"), exports);
|
|
24
22
|
__exportStar(require("./chunk"), exports);
|
|
25
23
|
__exportStar(require("./env"), exports);
|
package/dist/pub.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.publishMessage = publishMessage;
|
|
4
4
|
// src/pub.ts
|
|
5
5
|
const pubsub_1 = require("@google-cloud/pubsub");
|
|
6
|
+
const logger_1 = require("./logger");
|
|
6
7
|
let cachedPubSub = null;
|
|
7
8
|
function getPubSub(projectId) {
|
|
8
9
|
if (!projectId)
|
|
@@ -26,11 +27,11 @@ async function publishMessage(projectId, topicName, envelope) {
|
|
|
26
27
|
const messageId = await topic.publishMessage({
|
|
27
28
|
data
|
|
28
29
|
});
|
|
29
|
-
|
|
30
|
+
(0, logger_1.log)(logger_1.LogLevel.INFO, 'Pub/Sub publish', { topicName, messageId });
|
|
30
31
|
return messageId;
|
|
31
32
|
}
|
|
32
33
|
catch (err) {
|
|
33
|
-
|
|
34
|
+
(0, logger_1.log)(logger_1.LogLevel.ERROR, 'publish failed', { error: err });
|
|
34
35
|
throw err;
|
|
35
36
|
}
|
|
36
37
|
}
|
package/dist/task.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.isRetryableCloudTasks = isRetryableCloudTasks;
|
|
|
4
4
|
exports.createTask = createTask;
|
|
5
5
|
// src/cloud-tasks.ts
|
|
6
6
|
const tasks_1 = require("@google-cloud/tasks");
|
|
7
|
+
const logger_1 = require("./logger");
|
|
7
8
|
const retry_1 = require("./retry");
|
|
8
9
|
const tasksClient = new tasks_1.CloudTasksClient();
|
|
9
10
|
// cloud-tasks errors can be gRPC-style (numeric code) or an Error with code string.
|
|
@@ -67,7 +68,11 @@ async function createTask(projectId, region, queueId, data, serviceAccount, audi
|
|
|
67
68
|
timeoutMs: 15000,
|
|
68
69
|
isRetryable: isRetryableCloudTasks,
|
|
69
70
|
onRetry: (err, attempt, delay) => {
|
|
70
|
-
|
|
71
|
+
(0, logger_1.log)(logger_1.LogLevel.WARNING, 'createTask retry', {
|
|
72
|
+
attempt,
|
|
73
|
+
delayMs: delay,
|
|
74
|
+
error: String(err?.message ?? err)
|
|
75
|
+
});
|
|
71
76
|
},
|
|
72
77
|
...opts.retryOptions // allow overrides
|
|
73
78
|
};
|
|
@@ -93,11 +98,13 @@ async function createTask(projectId, region, queueId, data, serviceAccount, audi
|
|
|
93
98
|
if (err?.original?.code === 6 ||
|
|
94
99
|
err?.code === 6 ||
|
|
95
100
|
String(err?.original?.code).toUpperCase().includes('ALREADY_EXISTS')) {
|
|
96
|
-
|
|
101
|
+
(0, logger_1.log)(logger_1.LogLevel.WARNING, 'createTask — task already exists, returning existing name', {
|
|
102
|
+
taskName: expectedName
|
|
103
|
+
});
|
|
97
104
|
return expectedName;
|
|
98
105
|
}
|
|
99
106
|
}
|
|
100
|
-
|
|
107
|
+
(0, logger_1.log)(logger_1.LogLevel.ERROR, 'createTask — final failure after retries', { error: err?.message ?? err });
|
|
101
108
|
throw err; // rethrow (or return null if you prefer)
|
|
102
109
|
}
|
|
103
110
|
}
|
package/dist/types/api.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { CardType } from '../enums/card';
|
|
2
|
+
import type { PriceChartingImages, PriceChartingPrice } from './pricecharting';
|
|
1
3
|
/** Successful non-paginated DGC API response. */
|
|
2
4
|
export type ApiResponse<T> = {
|
|
3
5
|
data: T;
|
|
@@ -10,3 +12,187 @@ export type PaginatedApiResponse<T> = {
|
|
|
10
12
|
totalCount: number;
|
|
11
13
|
data: T[];
|
|
12
14
|
};
|
|
15
|
+
export type PriceChartingApiCard = {
|
|
16
|
+
priceChartingId: number;
|
|
17
|
+
name: string;
|
|
18
|
+
set: string;
|
|
19
|
+
number: string | null;
|
|
20
|
+
releaseDate?: string;
|
|
21
|
+
price: PriceChartingPrice;
|
|
22
|
+
images?: PriceChartingImages;
|
|
23
|
+
type: CardType;
|
|
24
|
+
version: string;
|
|
25
|
+
};
|
|
26
|
+
export type PriceChartingVariantApiCard = PriceChartingApiCard & {
|
|
27
|
+
variant: string;
|
|
28
|
+
};
|
|
29
|
+
/** An unsuccessful API response. Use the HTTP status and message together. */
|
|
30
|
+
export type ApiError = {
|
|
31
|
+
/** Message explaining why the request failed. */
|
|
32
|
+
error: string;
|
|
33
|
+
};
|
|
34
|
+
/** A grading change was accepted. Read the card again to show its current state. */
|
|
35
|
+
export type ApiSuccess = {
|
|
36
|
+
success: true;
|
|
37
|
+
};
|
|
38
|
+
/** Available card image URLs. Missing image sizes are omitted. */
|
|
39
|
+
export type ApiImages = NonNullable<PriceChartingApiCard['images']>;
|
|
40
|
+
/** Prices in cents. Unavailable prices are null; missing price fields are omitted. */
|
|
41
|
+
export type ApiPrice = Partial<PriceChartingPrice>;
|
|
42
|
+
/** Card details for catalog screens. Optional fields are omitted when unavailable. */
|
|
43
|
+
export type ApiCardCore = Partial<Omit<PriceChartingApiCard, 'price' | 'type'>> & {
|
|
44
|
+
/** Available prices in cents. */
|
|
45
|
+
price?: ApiPrice;
|
|
46
|
+
/** Card type, such as pokemon or baseball. */
|
|
47
|
+
type?: string;
|
|
48
|
+
};
|
|
49
|
+
/** Card details with an optional link to its set. */
|
|
50
|
+
export type ApiCard = ApiCardCore & {
|
|
51
|
+
/** Set ID to use with /sets/{id}/cards. */
|
|
52
|
+
setId?: string;
|
|
53
|
+
};
|
|
54
|
+
/** A batch card result with its printing label when available. */
|
|
55
|
+
export type ApiCardWithVariant = ApiCard & Partial<Pick<PriceChartingVariantApiCard, 'variant'>>;
|
|
56
|
+
/** A card variant returned for a set, without a separate setId field. */
|
|
57
|
+
export type ApiSetCardVariant = ApiCardCore & Partial<Pick<PriceChartingVariantApiCard, 'variant'>>;
|
|
58
|
+
/** Paginated card search results. totalCount is capped at 1000. */
|
|
59
|
+
export type ApiCardPage = PaginatedApiResponse<ApiCard>;
|
|
60
|
+
/** Paginated cards in a set. totalCount is the full matching count. */
|
|
61
|
+
export type ApiSetCardPage = PaginatedApiResponse<ApiCardCore>;
|
|
62
|
+
/** Card IDs for a batch detail request. Supply at least one numeric ID. */
|
|
63
|
+
export type ApiBatchRequest = {
|
|
64
|
+
ids: number[];
|
|
65
|
+
};
|
|
66
|
+
/** One legacy trading-card price observation. */
|
|
67
|
+
export type ApiLegacyHistoryEntry = {
|
|
68
|
+
/** Price date, normally YYYY-MM-DD. */
|
|
69
|
+
date: string;
|
|
70
|
+
/** averageSellPrice is in dollars; the other values are zero placeholders. */
|
|
71
|
+
cardmarket: {
|
|
72
|
+
averageSellPrice?: number;
|
|
73
|
+
avg1?: 0;
|
|
74
|
+
avg30?: 0;
|
|
75
|
+
avg7?: 0;
|
|
76
|
+
germanProLow?: 0;
|
|
77
|
+
lowPrice?: 0;
|
|
78
|
+
lowPriceExPlus?: 0;
|
|
79
|
+
reverseHoloAvg1?: 0;
|
|
80
|
+
reverseHoloAvg30?: 0;
|
|
81
|
+
reverseHoloAvg7?: 0;
|
|
82
|
+
reverseHoloLow?: 0;
|
|
83
|
+
reverseHoloSell?: 0;
|
|
84
|
+
reverseHoloTrend?: 0;
|
|
85
|
+
suggestedPrice?: 0;
|
|
86
|
+
trendPrice?: 0;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
/** One market-price observation for a UTC date. Prices are cents or null. */
|
|
90
|
+
export type ApiMarketHistoryEntry = {
|
|
91
|
+
date: string;
|
|
92
|
+
price: Partial<Pick<PriceChartingPrice, 'loose' | 'retailLooseBuy' | 'retailLooseSell'>>;
|
|
93
|
+
};
|
|
94
|
+
/** The selected card, condition, printing and language for a price chart. */
|
|
95
|
+
export type ApiConditionHistoryMeta = {
|
|
96
|
+
/** Requested ID: a number for numeric IDs, or a string for legacy Pokemon IDs. */
|
|
97
|
+
assetId: number | string;
|
|
98
|
+
priceChartingId: number;
|
|
99
|
+
tcgplayerId: string;
|
|
100
|
+
/** ID of the pricing variant used for this chart. */
|
|
101
|
+
id: string;
|
|
102
|
+
/** Full condition name, such as Near Mint. */
|
|
103
|
+
condition: string;
|
|
104
|
+
printing: string;
|
|
105
|
+
language: string;
|
|
106
|
+
/** Current price in cents, or null when unavailable. */
|
|
107
|
+
price: number | null;
|
|
108
|
+
/** Last price update as Unix time in seconds, or null when unavailable. */
|
|
109
|
+
lastUpdated: number | null;
|
|
110
|
+
};
|
|
111
|
+
/** Condition-specific prices, ordered oldest to newest, and chart labels. */
|
|
112
|
+
export type ApiConditionHistoryResponse = ApiResponse<{
|
|
113
|
+
/** UTC price date in YYYY-MM-DD format. */
|
|
114
|
+
date: string;
|
|
115
|
+
/** Price in cents, or null when unavailable. */
|
|
116
|
+
price: Pick<PriceChartingPrice, 'loose'>;
|
|
117
|
+
}[]> & {
|
|
118
|
+
meta: ApiConditionHistoryMeta;
|
|
119
|
+
};
|
|
120
|
+
/** A master set available for browsing. */
|
|
121
|
+
export type ApiMasterSet = {
|
|
122
|
+
/** 24-character set ID to use with /sets/{id}/cards. */
|
|
123
|
+
id: string;
|
|
124
|
+
name: string;
|
|
125
|
+
/** Card type, such as pokemon. */
|
|
126
|
+
type: string;
|
|
127
|
+
releaseDate?: string;
|
|
128
|
+
logo?: string;
|
|
129
|
+
};
|
|
130
|
+
/** Paginated set search results. totalCount includes matches outside this page. */
|
|
131
|
+
export type ApiMasterSetPage = PaginatedApiResponse<ApiMasterSet>;
|
|
132
|
+
/** The master set available for one requested card ID. */
|
|
133
|
+
export type ApiMasterRelationship = {
|
|
134
|
+
assetId: number;
|
|
135
|
+
/** Master-set ID, or null when no master set is available. */
|
|
136
|
+
masterIdentifier: string | null;
|
|
137
|
+
isExist: boolean;
|
|
138
|
+
};
|
|
139
|
+
/** A catalog group and its master sets. Empty groups have an empty sets array. */
|
|
140
|
+
export type ApiGroup = {
|
|
141
|
+
name: string;
|
|
142
|
+
sets: ApiMasterSet[];
|
|
143
|
+
};
|
|
144
|
+
type MaterializedApiImages = {
|
|
145
|
+
[Key in keyof ApiImages]: ApiImages[Key];
|
|
146
|
+
};
|
|
147
|
+
interface ApiImageMetadata extends MaterializedApiImages {
|
|
148
|
+
[key: string]: unknown;
|
|
149
|
+
}
|
|
150
|
+
/** Card identified from a photo. Required nullable fields remain present as null. */
|
|
151
|
+
export type ApiImageCard = Pick<PriceChartingApiCard, 'priceChartingId' | 'name' | 'number' | 'version'> & {
|
|
152
|
+
set: string | null;
|
|
153
|
+
releaseDate: string | null;
|
|
154
|
+
/** Available prices in cents, or null when unavailable. */
|
|
155
|
+
price: Record<string, unknown> | null;
|
|
156
|
+
images: ApiImageMetadata | null;
|
|
157
|
+
type: string | null;
|
|
158
|
+
/** Set ID to use with /sets/{id}/cards. Omitted when unavailable. */
|
|
159
|
+
setId?: string;
|
|
160
|
+
};
|
|
161
|
+
/** Photo search result. Open data only when matched is true. */
|
|
162
|
+
export type ApiImageMatch = {
|
|
163
|
+
matched: boolean;
|
|
164
|
+
reason?: string;
|
|
165
|
+
score: number | null;
|
|
166
|
+
gap: number | null;
|
|
167
|
+
data: ApiImageCard | null;
|
|
168
|
+
};
|
|
169
|
+
/** Card count and percentage for one grade group. */
|
|
170
|
+
export type ApiPopulationBucket = {
|
|
171
|
+
/** Grade from 0.5 to 10 in half-point steps. */
|
|
172
|
+
score: number;
|
|
173
|
+
count: number;
|
|
174
|
+
/** Percentage of the report total, rounded to two decimal places. */
|
|
175
|
+
percent: number;
|
|
176
|
+
};
|
|
177
|
+
/** Exactly 20 grade groups, ordered from 0.5 to 10, including empty groups. */
|
|
178
|
+
export type ApiPopulation = {
|
|
179
|
+
status: 'success';
|
|
180
|
+
data: ApiPopulationBucket[];
|
|
181
|
+
};
|
|
182
|
+
/** Card details in the standard data envelope. */
|
|
183
|
+
export type ApiCardResponse = ApiResponse<ApiCard>;
|
|
184
|
+
/** Batch card details with variant labels in the standard data envelope. */
|
|
185
|
+
export type ApiCardsResponse = ApiResponse<ApiCardWithVariant[]>;
|
|
186
|
+
/** Legacy price observations in the priceData envelope. */
|
|
187
|
+
export type ApiLegacyHistoryResponse = {
|
|
188
|
+
priceData: ApiLegacyHistoryEntry[];
|
|
189
|
+
};
|
|
190
|
+
/** Market-price observations in the standard data envelope. */
|
|
191
|
+
export type ApiMarketHistoryResponse = ApiResponse<ApiMarketHistoryEntry[]>;
|
|
192
|
+
/** Card variants in the standard data envelope. */
|
|
193
|
+
export type ApiVariantsResponse = ApiResponse<ApiSetCardVariant[]>;
|
|
194
|
+
/** Master-set relationships in the standard data envelope. */
|
|
195
|
+
export type ApiMasterRelationshipsResponse = ApiResponse<ApiMasterRelationship[]>;
|
|
196
|
+
/** Catalog groups and their master sets in the standard data envelope. */
|
|
197
|
+
export type ApiGroupsResponse = ApiResponse<ApiGroup[]>;
|
|
198
|
+
export {};
|
|
@@ -27,7 +27,7 @@ export type SalesVolumeEntry = {
|
|
|
27
27
|
date: string;
|
|
28
28
|
salesVolume: SalesVolume;
|
|
29
29
|
};
|
|
30
|
-
type
|
|
30
|
+
export type PriceChartingImages = {
|
|
31
31
|
tiny?: string;
|
|
32
32
|
small?: string;
|
|
33
33
|
normal?: string;
|
|
@@ -46,7 +46,7 @@ export type PriceChartingDbCard = {
|
|
|
46
46
|
priceHistory: PriceChartingPriceEntry[];
|
|
47
47
|
salesVolume: SalesVolume;
|
|
48
48
|
salesVolumeHistory: SalesVolumeEntry[];
|
|
49
|
-
images?:
|
|
49
|
+
images?: PriceChartingImages;
|
|
50
50
|
uploadStatus?: {
|
|
51
51
|
imagesUploaded?: boolean;
|
|
52
52
|
noImage?: boolean;
|
|
@@ -62,20 +62,6 @@ export type PriceChartingDbCardDto = Omit<PriceChartingDbCard, 'createdAt' | 'up
|
|
|
62
62
|
createdAt?: string;
|
|
63
63
|
updatedAt: string;
|
|
64
64
|
};
|
|
65
|
-
export type PriceChartingApiCard = {
|
|
66
|
-
priceChartingId: number;
|
|
67
|
-
name: string;
|
|
68
|
-
set: string;
|
|
69
|
-
number: string | null;
|
|
70
|
-
releaseDate?: string;
|
|
71
|
-
price: PriceChartingPrice;
|
|
72
|
-
images?: Image;
|
|
73
|
-
type: CardType;
|
|
74
|
-
version: string;
|
|
75
|
-
};
|
|
76
|
-
export type PriceChartingVariantApiCard = PriceChartingApiCard & {
|
|
77
|
-
variant: string;
|
|
78
|
-
};
|
|
79
65
|
export type PriceChartingDbSet = {
|
|
80
66
|
type: CardType;
|
|
81
67
|
consoleName: string;
|
|
@@ -83,4 +69,3 @@ export type PriceChartingDbSet = {
|
|
|
83
69
|
createdAt: Date;
|
|
84
70
|
updatedAt: Date;
|
|
85
71
|
};
|
|
86
|
-
export {};
|
package/package.json
CHANGED
package/dist/tw/utils.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function isValidWebhookSignature(secret: string, body: string, signature: string): boolean;
|
package/dist/tw/utils.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.isValidWebhookSignature = isValidWebhookSignature;
|
|
7
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
-
const generateSignature = (body, secret) => {
|
|
9
|
-
return crypto_1.default.createHmac('sha256', secret).update(body).digest('hex');
|
|
10
|
-
};
|
|
11
|
-
function isValidWebhookSignature(secret, body, signature) {
|
|
12
|
-
const expectedSignature = generateSignature(body, secret);
|
|
13
|
-
const expectedBuffer = Buffer.from(expectedSignature);
|
|
14
|
-
const signatureBuffer = Buffer.from(signature);
|
|
15
|
-
if (expectedBuffer.length !== signatureBuffer.length) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
return crypto_1.default.timingSafeEqual(expectedBuffer, signatureBuffer);
|
|
19
|
-
}
|
package/dist/tw/wallet.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function pregenerateInAppWallet(twClientId: string, twSecretKey: string, email: string): Promise<string | null>;
|
package/dist/tw/wallet.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.pregenerateInAppWallet = pregenerateInAppWallet;
|
|
7
|
-
// src/tw/wallet.ts
|
|
8
|
-
const axios_1 = __importDefault(require("axios"));
|
|
9
|
-
const retry_1 = require("../retry");
|
|
10
|
-
async function pregenerateInAppWallet(twClientId, twSecretKey, email) {
|
|
11
|
-
if (!twClientId || !twSecretKey || !email) {
|
|
12
|
-
console.error('Missing client id or secret or email');
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
const doRequest = async () => {
|
|
16
|
-
const res = await axios_1.default.post('https://in-app-wallet.thirdweb.com/api/v1/pregenerate', { strategy: 'email', email }, {
|
|
17
|
-
headers: {
|
|
18
|
-
'Content-Type': 'application/json',
|
|
19
|
-
'x-client-id': twClientId,
|
|
20
|
-
'x-secret-key': twSecretKey
|
|
21
|
-
},
|
|
22
|
-
timeout: 10000
|
|
23
|
-
});
|
|
24
|
-
const wallet = res.data?.wallet;
|
|
25
|
-
if (!wallet || !wallet.address) {
|
|
26
|
-
// server returned 2xx but unexpected shape — don't retry, treat as final failure
|
|
27
|
-
console.error('Invalid wallet response shape', { status: res.status, data: res.data });
|
|
28
|
-
throw new Error('Invalid wallet response');
|
|
29
|
-
}
|
|
30
|
-
return wallet.address;
|
|
31
|
-
};
|
|
32
|
-
const opts = {
|
|
33
|
-
retries: 3,
|
|
34
|
-
baseDelayMs: 300,
|
|
35
|
-
maxDelayMs: 2000,
|
|
36
|
-
timeoutMs: 15000,
|
|
37
|
-
isRetryable: retry_1.isRetryableAxios,
|
|
38
|
-
onRetry: (err, attempt, delay) => {
|
|
39
|
-
console.warn(`pregenerateInAppWallet: retry #${attempt} in ${delay}ms — ${String(err?.message)}`);
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
try {
|
|
43
|
-
const address = await (0, retry_1.retry)(() => doRequest(), opts);
|
|
44
|
-
return address;
|
|
45
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
-
}
|
|
47
|
-
catch (err) {
|
|
48
|
-
// final failure after retries
|
|
49
|
-
console.error('pregenerateInAppWallet: final failure', {
|
|
50
|
-
message: err?.message,
|
|
51
|
-
// include axios response data when possible
|
|
52
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
53
|
-
responseData: err?.response?.data ?? err?.cause ?? err.original ?? null
|
|
54
|
-
});
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
}
|