@nexus-cross/pop 1.3.10-beta.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.
@@ -0,0 +1,1175 @@
1
+ import { C as CryptoPort, g as Secret, t as SecretHash, H as Hex, A as Address, d as ClaimSignerPort, S as SafeDropChainPort, k as DropState, I as Id, a as SafeDropApiPort, u as SocialIdentifier, O as OAuthProof, i as DropInbox, E as Envelope, L as LeaderboardEntry, n as PopEventName, m as HistoryPage, X as XConnection, h as BatchClaimSignature, o as SafeDrop } from '../createSafeDrop-qoNG59jB.js';
2
+ import { PublicClient, WalletClient, Chain, Transport } from 'viem';
3
+ import { X as XAuthPort, a as XTokenResult } from '../XAuthPort-BNJePosj.js';
4
+
5
+ /**
6
+ * viem 기반 CryptoPort 구현. 컨트랙트 ABI 불필요 — 순수 암호 연산.
7
+ *
8
+ * keccak256는 one-pop-fe와 동일하게 `keccak256(toBytes(secret))`. withdraw의
9
+ * secret 인자도 `toHex(toBytes(secret))`라 인코딩이 정합한다. (0x로 시작하지 않는
10
+ * 일반 문자열은 utf8로, randomSecret도 0x 없는 hex라 utf8로 처리됨.)
11
+ */
12
+ declare class ViemCryptoAdapter implements CryptoPort {
13
+ keccak256(input: Secret): SecretHash;
14
+ /** 32바이트 CSPRNG → 0x 없는 hex 64자 (URL-safe). */
15
+ randomSecret(): Secret;
16
+ /**
17
+ * digest(이미 EIP-712 해시)에 대한 서명자 복원. `hashMessage` 같은 추가 프리픽스를
18
+ * 붙이지 않는다 — 컨트랙트도 `ECDSA.recover(digest, sig)`로 그대로 검증한다.
19
+ */
20
+ recoverAddress(params: {
21
+ digest: Hex;
22
+ signature: Hex;
23
+ }): Promise<Address>;
24
+ }
25
+
26
+ /**
27
+ * 임시 claim 개인키로 claimDigest에 raw ECDSA 서명 → serialize (브라우저 로컬).
28
+ * (컨트랙트 withdraw가 서명에서 signer=claimAddr를 recover한다.)
29
+ */
30
+ declare class ViemClaimSignerAdapter implements ClaimSignerPort {
31
+ signDigest(params: {
32
+ claimKey: Hex;
33
+ digest: Hex;
34
+ }): Promise<Hex>;
35
+ }
36
+
37
+ interface ViemSafeDropChainAdapterOptions {
38
+ address: Address;
39
+ publicClient: PublicClient;
40
+ /** approve/deposit/refund 서명용 지갑(연결된 MetaMask 등). */
41
+ walletClient: WalletClient;
42
+ chain: Chain;
43
+ /** withdraw용 임시 지갑 client의 RPC transport. 기본 http()(chain.rpcUrls). */
44
+ transport?: Transport;
45
+ /** withdraw gas/fee override. 기본 DEFAULT_WITHDRAW_GAS(gas-abstraction 대응). */
46
+ withdrawFees?: {
47
+ gas?: bigint;
48
+ maxFeePerGas?: bigint;
49
+ maxPriorityFeePerGas?: bigint;
50
+ };
51
+ /**
52
+ * true면 EIP-2612 permit 예치를 쓴다(approve tx 없음, 서명 1회 + tx 1회).
53
+ * 배포본마다 deposit 시그니처가 다르므로 opt-in이다 — permit deposit이 없는
54
+ * 컨트랙트에 켜면 셀렉터가 없어 revert한다. 토큰도 permit을 지원해야 한다.
55
+ */
56
+ permit?: boolean;
57
+ }
58
+ /**
59
+ * SafeDrop 컨트랙트 어댑터 (viem). ABI: src/infrastructure/safedrop_abi.json.
60
+ * 드롭 키는 claimAddr, id는 소셜 식별자 string. 쓰기는 receipt success까지 확인.
61
+ */
62
+ declare class ViemSafeDropChainAdapter implements SafeDropChainPort {
63
+ private readonly address;
64
+ private readonly publicClient;
65
+ private readonly walletClient;
66
+ private readonly chain;
67
+ private readonly transport;
68
+ private readonly withdrawFees;
69
+ /**
70
+ * permit 옵션을 켠 경우에만 채워진다. DepositUseCase는 이 프로퍼티의 존재
71
+ * 여부로 approve tx를 건너뛸지 판단하므로, 미지원 배포본에서는 undefined여야 한다.
72
+ */
73
+ readonly depositWithPermit?: SafeDropChainPort['depositWithPermit'];
74
+ constructor(options: ViemSafeDropChainAdapterOptions);
75
+ /**
76
+ * drops(claimAddr). 배포본에 따라 반환 필드가 8개(Foundry ABI) 또는 5개(permit
77
+ * 배포본)다 — 셀렉터가 같으므로 raw call 1회 후 디코딩만 나눈다. 8필드를 먼저
78
+ * 시도하는 이유: 짧은 데이터(5필드=192B)를 8필드로 읽으면 **에러가 나서** 안전하게
79
+ * 폴백되지만, 반대 순서면 8필드 데이터를 5필드로 조용히 오독한다.
80
+ */
81
+ getDrop(claimAddress: Address): Promise<DropState | null>;
82
+ /** 에스크로가 고정한 단일 ERC20. 5필드 배포본에서 drop.token을 채운다. */
83
+ private escrowToken;
84
+ getClaimDigest(params: {
85
+ recipient: Address;
86
+ id: Id;
87
+ salt: Hex;
88
+ }): Promise<Hex>;
89
+ approve(params: {
90
+ token: Address;
91
+ amount: bigint;
92
+ }): Promise<Hex>;
93
+ deposit(params: {
94
+ claimAddress: Address;
95
+ token: Address;
96
+ amount: bigint;
97
+ id: Id;
98
+ secretHash: SecretHash;
99
+ }): Promise<{
100
+ txHash: Hex;
101
+ }>;
102
+ /**
103
+ * permit 예치. approve tx 없이 typed-data 서명 1회 + deposit tx 1회.
104
+ * 이 배포본의 deposit에는 token 인자가 없다 — 컨트랙트가 token()으로 고정한다.
105
+ */
106
+ private permitDeposit;
107
+ /**
108
+ * permit 서명 도메인. EIP-5267 eip712Domain()이 있으면 그 값을 쓰고, 없으면
109
+ * name() + version '1'로 폴백한다. version을 상수로 박으면 다른 버전을 쓰는
110
+ * 토큰에서 ecrecover가 조용히 실패해 deposit 내부 revert로만 드러난다.
111
+ */
112
+ private permitDomain;
113
+ withdraw(params: {
114
+ claimKey: Hex;
115
+ recipient: Address;
116
+ id: Id;
117
+ salt: Hex;
118
+ signature: Hex;
119
+ secret: Secret;
120
+ }): Promise<Hex>;
121
+ /** validatorNonceById는 **bytes32(id 해시)** 로 키잉된다 — 원문 string이 아니다. */
122
+ getValidatorNonce(params: {
123
+ id: Id;
124
+ }): Promise<bigint>;
125
+ /** 온체인 EIP-712 다이제스트. 로컬 재조립 대신 이 값으로 백엔드 서명을 검증한다. */
126
+ getValidatorClaimDigest(params: {
127
+ recipient: Address;
128
+ id: Id;
129
+ nonce: bigint;
130
+ deadline: bigint;
131
+ }): Promise<Hex>;
132
+ getValidator(): Promise<Address>;
133
+ getClaimedRecipient(params: {
134
+ id: Id;
135
+ }): Promise<Address>;
136
+ getLiveDropCount(params: {
137
+ id: Id;
138
+ }): Promise<bigint>;
139
+ /**
140
+ * 개별 withdraw와 달리 **연결된 수령인 지갑**이 보낸다 — 컨트랙트가 msg.sender와
141
+ * 서명의 recipient를 대조하므로 임시 claim 지갑으로는 보낼 수 없다(가스 대납 대상도 아님).
142
+ * simulate를 먼저 돌려 `ValidatorSigExpired`/`InvalidValidatorNonce`/
143
+ * `ECDSAInvalidSignature`를 이름으로 드러낸다.
144
+ */
145
+ withdrawByValidator(params: {
146
+ recipient: Address;
147
+ id: Id;
148
+ nonce: bigint;
149
+ deadline: bigint;
150
+ maxCount: number;
151
+ signature: Hex;
152
+ }): Promise<Hex>;
153
+ refund(params: {
154
+ claimAddress: Address;
155
+ }): Promise<Hex>;
156
+ private sponsorWrite;
157
+ private confirm;
158
+ private recoverRevertName;
159
+ private requireAccount;
160
+ }
161
+
162
+ /**
163
+ * one-pop-api 엔드포인트 — 패키지 내부 상수. onramp/adapters/endpoints.ts와
164
+ * 동일한 컨벤션(Vite import.meta.env + Next literal process.env, override →
165
+ * 환경 식별 → 기본 URL, https 검증)을 따른다.
166
+ *
167
+ * 우선순위 (override):
168
+ * 1) `VITE_ONE_POP_API_BASE_URL` (Vite 빌드)
169
+ * 2) `NEXT_PUBLIC_ONE_POP_API_BASE_URL` (Next.js)
170
+ * 3) 환경 식별(`VITE_ONE_POP_ENVIRONMENT` / `NEXT_PUBLIC_ONE_POP_ENVIRONMENT`
171
+ * / `ONE_POP_ENVIRONMENT`)에 따라 DEFAULT_BASE_URL의 dev/stage/production
172
+ *
173
+ * 스펙: packages/pop/src/infrastructure/openapi.json (basePath `/api`)
174
+ */
175
+ type PopEnvironment = 'dev' | 'stage' | 'production';
176
+ interface PopApiPaths {
177
+ /** POST — 임시 claim 지갑 생성 (Bearer JWT). */
178
+ createWallet: string;
179
+ /** POST — pending 지갑 개인키 수령 (X OAuth 토큰). */
180
+ retrievePrivateKey: string;
181
+ /** GET — 수령 대기 인박스 (Bearer JWT + 활성 X 연결). */
182
+ drops: string;
183
+ /** GET — 카드 디자인 목록 (공개). */
184
+ envelopes: string;
185
+ /** GET — 토큰별 pending 잔액 상위 (공개). */
186
+ leaderboards: string;
187
+ /** GET — 내 온체인 이벤트 히스토리 (Bearer JWT). */
188
+ histories: string;
189
+ /** GET/POST/DELETE — X 연결 (Bearer JWT). */
190
+ xConnections: string;
191
+ /** POST — 일괄 수령 validator 서명 (Bearer JWT). */
192
+ batchClaimSignature: string;
193
+ /** GET — SSE 알림 스트림. pop은 구독하지 않는다(앱이 EventSource로 직접). */
194
+ eventsSubscribe: string;
195
+ }
196
+ declare const DEFAULT_POP_API_PATHS: PopApiPaths;
197
+ /** 환경변수(override → 환경 식별)로 one-pop-api base URL을 결정한다. */
198
+ declare function getOnePopApiBaseUrl(): string;
199
+ /** 환경변수(override → 기본)로 cross-auth base URL을 결정한다. */
200
+ declare function getCrossAuthBaseUrl(): string;
201
+
202
+ /**
203
+ * one-pop-api HTTP 어댑터. 스키마: packages/pop/src/infrastructure/openapi.json
204
+ * POST /wallets (Bearer JWT) → {address}
205
+ * POST /wallets/private-key (oauth_token 본문) → {address,private_key}
206
+ * GET /drops (Bearer JWT) → 수령 인박스
207
+ * GET /envelopes (공개) → 카드 디자인
208
+ * GET /leaderboards?token= (공개) → pending 상위
209
+ * GET /histories (Bearer JWT) → 온체인 이벤트
210
+ * GET|POST|DELETE /x-connections (Bearer JWT) → X 연결
211
+ * POST /batch-claim-signature (Bearer JWT) → ValidatorClaim 서명
212
+ *
213
+ * base URL은 미지정 시 환경변수로 결정(getOnePopApiBaseUrl).
214
+ * wei-scale 값은 응답의 10진 문자열 → BigInt로 변환해 내보낸다(CLAUDE.md §4).
215
+ */
216
+ interface HttpSafeDropApiAdapterOptions {
217
+ /** 미지정 시 환경변수(VITE_/NEXT_PUBLIC_ONE_POP_*)로 결정. */
218
+ baseUrl?: string;
219
+ /** SIWE JWT 공급자. Bearer 인증이 필요한 모든 호출이 사용한다. */
220
+ getJwt?: () => string | undefined | Promise<string | undefined>;
221
+ /** 테스트/SSR용 fetch 주입. 기본 globalThis.fetch. */
222
+ fetchImpl?: typeof fetch;
223
+ /** 엔드포인트 경로 override. 기본 DEFAULT_POP_API_PATHS. */
224
+ paths?: Partial<PopApiPaths>;
225
+ }
226
+ declare class HttpSafeDropApiAdapter implements SafeDropApiPort {
227
+ private readonly baseUrl;
228
+ private readonly fetchImpl;
229
+ private readonly getJwt?;
230
+ private readonly paths;
231
+ constructor(options?: HttpSafeDropApiAdapterOptions);
232
+ createClaimWallet(params: {
233
+ sender: Address;
234
+ recipient: SocialIdentifier;
235
+ message?: string;
236
+ envelopeId?: string;
237
+ }): Promise<{
238
+ claimAddress: Address;
239
+ }>;
240
+ retrieveClaimKey(params: {
241
+ senderAddress: Address;
242
+ oauth: OAuthProof;
243
+ }): Promise<{
244
+ claimKey: Hex;
245
+ claimAddress: Address;
246
+ }>;
247
+ listDrops(params?: {
248
+ token?: Address;
249
+ }): Promise<DropInbox>;
250
+ listEnvelopes(params?: {
251
+ locale?: string;
252
+ }): Promise<readonly Envelope[]>;
253
+ getLeaderboard(params: {
254
+ token: Address;
255
+ }): Promise<readonly LeaderboardEntry[]>;
256
+ listHistories(params?: {
257
+ event?: PopEventName;
258
+ page?: number;
259
+ pageSize?: number;
260
+ }): Promise<HistoryPage>;
261
+ getXConnection(): Promise<XConnection | null>;
262
+ connectX(params: {
263
+ oauth: OAuthProof;
264
+ }): Promise<XConnection>;
265
+ disconnectX(): Promise<void>;
266
+ requestBatchClaimSignature(params: {
267
+ id: Id;
268
+ oauth: OAuthProof;
269
+ nonce: bigint;
270
+ deadline: bigint;
271
+ }): Promise<BatchClaimSignature>;
272
+ private request;
273
+ }
274
+
275
+ declare const SAFEDROP_ABI: readonly [{
276
+ readonly type: "constructor";
277
+ readonly inputs: readonly [{
278
+ readonly name: "claimPeriod_";
279
+ readonly type: "uint64";
280
+ readonly internalType: "uint64";
281
+ }];
282
+ readonly stateMutability: "nonpayable";
283
+ }, {
284
+ readonly type: "function";
285
+ readonly name: "claimDigest";
286
+ readonly inputs: readonly [{
287
+ readonly name: "recipient";
288
+ readonly type: "address";
289
+ readonly internalType: "address";
290
+ }, {
291
+ readonly name: "id";
292
+ readonly type: "string";
293
+ readonly internalType: "string";
294
+ }, {
295
+ readonly name: "salt";
296
+ readonly type: "bytes32";
297
+ readonly internalType: "bytes32";
298
+ }];
299
+ readonly outputs: readonly [{
300
+ readonly name: "";
301
+ readonly type: "bytes32";
302
+ readonly internalType: "bytes32";
303
+ }];
304
+ readonly stateMutability: "view";
305
+ }, {
306
+ readonly type: "function";
307
+ readonly name: "claimPeriod";
308
+ readonly inputs: readonly [];
309
+ readonly outputs: readonly [{
310
+ readonly name: "";
311
+ readonly type: "uint64";
312
+ readonly internalType: "uint64";
313
+ }];
314
+ readonly stateMutability: "view";
315
+ }, {
316
+ readonly type: "function";
317
+ readonly name: "claimedRecipientOf";
318
+ readonly inputs: readonly [{
319
+ readonly name: "id";
320
+ readonly type: "string";
321
+ readonly internalType: "string";
322
+ }];
323
+ readonly outputs: readonly [{
324
+ readonly name: "";
325
+ readonly type: "address";
326
+ readonly internalType: "address";
327
+ }];
328
+ readonly stateMutability: "view";
329
+ }, {
330
+ readonly type: "function";
331
+ readonly name: "deposit";
332
+ readonly inputs: readonly [{
333
+ readonly name: "claimAddr";
334
+ readonly type: "address";
335
+ readonly internalType: "address";
336
+ }, {
337
+ readonly name: "token";
338
+ readonly type: "address";
339
+ readonly internalType: "contract IERC20";
340
+ }, {
341
+ readonly name: "amount";
342
+ readonly type: "uint256";
343
+ readonly internalType: "uint256";
344
+ }, {
345
+ readonly name: "id";
346
+ readonly type: "string";
347
+ readonly internalType: "string";
348
+ }, {
349
+ readonly name: "secretHash";
350
+ readonly type: "bytes32";
351
+ readonly internalType: "bytes32";
352
+ }];
353
+ readonly outputs: readonly [];
354
+ readonly stateMutability: "nonpayable";
355
+ }, {
356
+ readonly type: "function";
357
+ readonly name: "depositCountOf";
358
+ readonly inputs: readonly [{
359
+ readonly name: "sponsor";
360
+ readonly type: "address";
361
+ readonly internalType: "address";
362
+ }];
363
+ readonly outputs: readonly [{
364
+ readonly name: "";
365
+ readonly type: "uint256";
366
+ readonly internalType: "uint256";
367
+ }];
368
+ readonly stateMutability: "view";
369
+ }, {
370
+ readonly type: "function";
371
+ readonly name: "depositsBySponsor";
372
+ readonly inputs: readonly [{
373
+ readonly name: "sponsor";
374
+ readonly type: "address";
375
+ readonly internalType: "address";
376
+ }, {
377
+ readonly name: "";
378
+ readonly type: "uint256";
379
+ readonly internalType: "uint256";
380
+ }];
381
+ readonly outputs: readonly [{
382
+ readonly name: "claimAddr";
383
+ readonly type: "address";
384
+ readonly internalType: "address";
385
+ }, {
386
+ readonly name: "token";
387
+ readonly type: "address";
388
+ readonly internalType: "contract IERC20";
389
+ }, {
390
+ readonly name: "amount";
391
+ readonly type: "uint128";
392
+ readonly internalType: "uint128";
393
+ }, {
394
+ readonly name: "expiry";
395
+ readonly type: "uint64";
396
+ readonly internalType: "uint64";
397
+ }, {
398
+ readonly name: "secretHash";
399
+ readonly type: "bytes32";
400
+ readonly internalType: "bytes32";
401
+ }, {
402
+ readonly name: "id";
403
+ readonly type: "string";
404
+ readonly internalType: "string";
405
+ }];
406
+ readonly stateMutability: "view";
407
+ }, {
408
+ readonly type: "function";
409
+ readonly name: "depositsOf";
410
+ readonly inputs: readonly [{
411
+ readonly name: "sponsor";
412
+ readonly type: "address";
413
+ readonly internalType: "address";
414
+ }];
415
+ readonly outputs: readonly [{
416
+ readonly name: "";
417
+ readonly type: "tuple[]";
418
+ readonly internalType: "struct SafeDrop.DepositRecord[]";
419
+ readonly components: readonly [{
420
+ readonly name: "claimAddr";
421
+ readonly type: "address";
422
+ readonly internalType: "address";
423
+ }, {
424
+ readonly name: "token";
425
+ readonly type: "address";
426
+ readonly internalType: "contract IERC20";
427
+ }, {
428
+ readonly name: "amount";
429
+ readonly type: "uint128";
430
+ readonly internalType: "uint128";
431
+ }, {
432
+ readonly name: "expiry";
433
+ readonly type: "uint64";
434
+ readonly internalType: "uint64";
435
+ }, {
436
+ readonly name: "secretHash";
437
+ readonly type: "bytes32";
438
+ readonly internalType: "bytes32";
439
+ }, {
440
+ readonly name: "id";
441
+ readonly type: "string";
442
+ readonly internalType: "string";
443
+ }];
444
+ }];
445
+ readonly stateMutability: "view";
446
+ }, {
447
+ readonly type: "function";
448
+ readonly name: "drops";
449
+ readonly inputs: readonly [{
450
+ readonly name: "claimAddr";
451
+ readonly type: "address";
452
+ readonly internalType: "address";
453
+ }];
454
+ readonly outputs: readonly [{
455
+ readonly name: "sponsor";
456
+ readonly type: "address";
457
+ readonly internalType: "address";
458
+ }, {
459
+ readonly name: "recordIndex";
460
+ readonly type: "uint96";
461
+ readonly internalType: "uint96";
462
+ }, {
463
+ readonly name: "token";
464
+ readonly type: "address";
465
+ readonly internalType: "contract IERC20";
466
+ }, {
467
+ readonly name: "amount";
468
+ readonly type: "uint128";
469
+ readonly internalType: "uint128";
470
+ }, {
471
+ readonly name: "expiry";
472
+ readonly type: "uint64";
473
+ readonly internalType: "uint64";
474
+ }, {
475
+ readonly name: "secretHash";
476
+ readonly type: "bytes32";
477
+ readonly internalType: "bytes32";
478
+ }, {
479
+ readonly name: "salt";
480
+ readonly type: "bytes32";
481
+ readonly internalType: "bytes32";
482
+ }, {
483
+ readonly name: "id";
484
+ readonly type: "string";
485
+ readonly internalType: "string";
486
+ }];
487
+ readonly stateMutability: "view";
488
+ }, {
489
+ readonly type: "function";
490
+ readonly name: "eip712Domain";
491
+ readonly inputs: readonly [];
492
+ readonly outputs: readonly [{
493
+ readonly name: "fields";
494
+ readonly type: "bytes1";
495
+ readonly internalType: "bytes1";
496
+ }, {
497
+ readonly name: "name";
498
+ readonly type: "string";
499
+ readonly internalType: "string";
500
+ }, {
501
+ readonly name: "version";
502
+ readonly type: "string";
503
+ readonly internalType: "string";
504
+ }, {
505
+ readonly name: "chainId";
506
+ readonly type: "uint256";
507
+ readonly internalType: "uint256";
508
+ }, {
509
+ readonly name: "verifyingContract";
510
+ readonly type: "address";
511
+ readonly internalType: "address";
512
+ }, {
513
+ readonly name: "salt";
514
+ readonly type: "bytes32";
515
+ readonly internalType: "bytes32";
516
+ }, {
517
+ readonly name: "extensions";
518
+ readonly type: "uint256[]";
519
+ readonly internalType: "uint256[]";
520
+ }];
521
+ readonly stateMutability: "view";
522
+ }, {
523
+ readonly type: "function";
524
+ readonly name: "liveClaimAddrsById";
525
+ readonly inputs: readonly [{
526
+ readonly name: "id";
527
+ readonly type: "string";
528
+ readonly internalType: "string";
529
+ }];
530
+ readonly outputs: readonly [{
531
+ readonly name: "";
532
+ readonly type: "address[]";
533
+ readonly internalType: "address[]";
534
+ }];
535
+ readonly stateMutability: "view";
536
+ }, {
537
+ readonly type: "function";
538
+ readonly name: "liveDropCountById";
539
+ readonly inputs: readonly [{
540
+ readonly name: "id";
541
+ readonly type: "string";
542
+ readonly internalType: "string";
543
+ }];
544
+ readonly outputs: readonly [{
545
+ readonly name: "";
546
+ readonly type: "uint256";
547
+ readonly internalType: "uint256";
548
+ }];
549
+ readonly stateMutability: "view";
550
+ }, {
551
+ readonly type: "function";
552
+ readonly name: "liveDropsById";
553
+ readonly inputs: readonly [{
554
+ readonly name: "id";
555
+ readonly type: "string";
556
+ readonly internalType: "string";
557
+ }];
558
+ readonly outputs: readonly [{
559
+ readonly name: "claimAddrs";
560
+ readonly type: "address[]";
561
+ readonly internalType: "address[]";
562
+ }, {
563
+ readonly name: "records";
564
+ readonly type: "tuple[]";
565
+ readonly internalType: "struct SafeDrop.Drop[]";
566
+ readonly components: readonly [{
567
+ readonly name: "sponsor";
568
+ readonly type: "address";
569
+ readonly internalType: "address";
570
+ }, {
571
+ readonly name: "recordIndex";
572
+ readonly type: "uint96";
573
+ readonly internalType: "uint96";
574
+ }, {
575
+ readonly name: "token";
576
+ readonly type: "address";
577
+ readonly internalType: "contract IERC20";
578
+ }, {
579
+ readonly name: "amount";
580
+ readonly type: "uint128";
581
+ readonly internalType: "uint128";
582
+ }, {
583
+ readonly name: "expiry";
584
+ readonly type: "uint64";
585
+ readonly internalType: "uint64";
586
+ }, {
587
+ readonly name: "secretHash";
588
+ readonly type: "bytes32";
589
+ readonly internalType: "bytes32";
590
+ }, {
591
+ readonly name: "salt";
592
+ readonly type: "bytes32";
593
+ readonly internalType: "bytes32";
594
+ }, {
595
+ readonly name: "id";
596
+ readonly type: "string";
597
+ readonly internalType: "string";
598
+ }];
599
+ }];
600
+ readonly stateMutability: "view";
601
+ }, {
602
+ readonly type: "function";
603
+ readonly name: "refund";
604
+ readonly inputs: readonly [{
605
+ readonly name: "claimAddr";
606
+ readonly type: "address";
607
+ readonly internalType: "address";
608
+ }];
609
+ readonly outputs: readonly [];
610
+ readonly stateMutability: "nonpayable";
611
+ }, {
612
+ readonly type: "function";
613
+ readonly name: "unclaimedCountOf";
614
+ readonly inputs: readonly [{
615
+ readonly name: "sponsor";
616
+ readonly type: "address";
617
+ readonly internalType: "address";
618
+ }];
619
+ readonly outputs: readonly [{
620
+ readonly name: "";
621
+ readonly type: "uint256";
622
+ readonly internalType: "uint256";
623
+ }];
624
+ readonly stateMutability: "view";
625
+ }, {
626
+ readonly type: "function";
627
+ readonly name: "unclaimedDepositsOf";
628
+ readonly inputs: readonly [{
629
+ readonly name: "sponsor";
630
+ readonly type: "address";
631
+ readonly internalType: "address";
632
+ }];
633
+ readonly outputs: readonly [{
634
+ readonly name: "records";
635
+ readonly type: "tuple[]";
636
+ readonly internalType: "struct SafeDrop.DepositRecord[]";
637
+ readonly components: readonly [{
638
+ readonly name: "claimAddr";
639
+ readonly type: "address";
640
+ readonly internalType: "address";
641
+ }, {
642
+ readonly name: "token";
643
+ readonly type: "address";
644
+ readonly internalType: "contract IERC20";
645
+ }, {
646
+ readonly name: "amount";
647
+ readonly type: "uint128";
648
+ readonly internalType: "uint128";
649
+ }, {
650
+ readonly name: "expiry";
651
+ readonly type: "uint64";
652
+ readonly internalType: "uint64";
653
+ }, {
654
+ readonly name: "secretHash";
655
+ readonly type: "bytes32";
656
+ readonly internalType: "bytes32";
657
+ }, {
658
+ readonly name: "id";
659
+ readonly type: "string";
660
+ readonly internalType: "string";
661
+ }];
662
+ }];
663
+ readonly stateMutability: "view";
664
+ }, {
665
+ readonly type: "function";
666
+ readonly name: "unclaimedIndexesOf";
667
+ readonly inputs: readonly [{
668
+ readonly name: "sponsor";
669
+ readonly type: "address";
670
+ readonly internalType: "address";
671
+ }];
672
+ readonly outputs: readonly [{
673
+ readonly name: "";
674
+ readonly type: "uint256[]";
675
+ readonly internalType: "uint256[]";
676
+ }];
677
+ readonly stateMutability: "view";
678
+ }, {
679
+ readonly type: "function";
680
+ readonly name: "withdraw";
681
+ readonly inputs: readonly [{
682
+ readonly name: "recipient";
683
+ readonly type: "address";
684
+ readonly internalType: "address";
685
+ }, {
686
+ readonly name: "id";
687
+ readonly type: "string";
688
+ readonly internalType: "string";
689
+ }, {
690
+ readonly name: "salt";
691
+ readonly type: "bytes32";
692
+ readonly internalType: "bytes32";
693
+ }, {
694
+ readonly name: "signature";
695
+ readonly type: "bytes";
696
+ readonly internalType: "bytes";
697
+ }, {
698
+ readonly name: "secret";
699
+ readonly type: "bytes";
700
+ readonly internalType: "bytes";
701
+ }];
702
+ readonly outputs: readonly [];
703
+ readonly stateMutability: "nonpayable";
704
+ }, {
705
+ readonly type: "event";
706
+ readonly name: "Deposited";
707
+ readonly inputs: readonly [{
708
+ readonly name: "claimAddr";
709
+ readonly type: "address";
710
+ readonly indexed: true;
711
+ readonly internalType: "address";
712
+ }, {
713
+ readonly name: "sponsor";
714
+ readonly type: "address";
715
+ readonly indexed: true;
716
+ readonly internalType: "address";
717
+ }, {
718
+ readonly name: "token";
719
+ readonly type: "address";
720
+ readonly indexed: true;
721
+ readonly internalType: "address";
722
+ }, {
723
+ readonly name: "amount";
724
+ readonly type: "uint256";
725
+ readonly indexed: false;
726
+ readonly internalType: "uint256";
727
+ }, {
728
+ readonly name: "id";
729
+ readonly type: "string";
730
+ readonly indexed: false;
731
+ readonly internalType: "string";
732
+ }, {
733
+ readonly name: "expiry";
734
+ readonly type: "uint64";
735
+ readonly indexed: false;
736
+ readonly internalType: "uint64";
737
+ }, {
738
+ readonly name: "secretHash";
739
+ readonly type: "bytes32";
740
+ readonly indexed: false;
741
+ readonly internalType: "bytes32";
742
+ }];
743
+ readonly anonymous: false;
744
+ }, {
745
+ readonly type: "event";
746
+ readonly name: "EIP712DomainChanged";
747
+ readonly inputs: readonly [];
748
+ readonly anonymous: false;
749
+ }, {
750
+ readonly type: "event";
751
+ readonly name: "Refunded";
752
+ readonly inputs: readonly [{
753
+ readonly name: "claimAddr";
754
+ readonly type: "address";
755
+ readonly indexed: true;
756
+ readonly internalType: "address";
757
+ }, {
758
+ readonly name: "sponsor";
759
+ readonly type: "address";
760
+ readonly indexed: true;
761
+ readonly internalType: "address";
762
+ }, {
763
+ readonly name: "id";
764
+ readonly type: "string";
765
+ readonly indexed: false;
766
+ readonly internalType: "string";
767
+ }, {
768
+ readonly name: "amount";
769
+ readonly type: "uint256";
770
+ readonly indexed: false;
771
+ readonly internalType: "uint256";
772
+ }];
773
+ readonly anonymous: false;
774
+ }, {
775
+ readonly type: "event";
776
+ readonly name: "Withdrawn";
777
+ readonly inputs: readonly [{
778
+ readonly name: "claimAddr";
779
+ readonly type: "address";
780
+ readonly indexed: true;
781
+ readonly internalType: "address";
782
+ }, {
783
+ readonly name: "recipient";
784
+ readonly type: "address";
785
+ readonly indexed: true;
786
+ readonly internalType: "address";
787
+ }, {
788
+ readonly name: "sponsor";
789
+ readonly type: "address";
790
+ readonly indexed: true;
791
+ readonly internalType: "address";
792
+ }, {
793
+ readonly name: "id";
794
+ readonly type: "string";
795
+ readonly indexed: false;
796
+ readonly internalType: "string";
797
+ }, {
798
+ readonly name: "amount";
799
+ readonly type: "uint256";
800
+ readonly indexed: false;
801
+ readonly internalType: "uint256";
802
+ }];
803
+ readonly anonymous: false;
804
+ }, {
805
+ readonly type: "error";
806
+ readonly name: "AmountOverflow";
807
+ readonly inputs: readonly [];
808
+ }, {
809
+ readonly type: "error";
810
+ readonly name: "DropAlreadyExists";
811
+ readonly inputs: readonly [];
812
+ }, {
813
+ readonly type: "error";
814
+ readonly name: "DropExpired";
815
+ readonly inputs: readonly [];
816
+ }, {
817
+ readonly type: "error";
818
+ readonly name: "DropNotExpired";
819
+ readonly inputs: readonly [];
820
+ }, {
821
+ readonly type: "error";
822
+ readonly name: "DropNotFound";
823
+ readonly inputs: readonly [];
824
+ }, {
825
+ readonly type: "error";
826
+ readonly name: "DuplicateDropForId";
827
+ readonly inputs: readonly [];
828
+ }, {
829
+ readonly type: "error";
830
+ readonly name: "ECDSAInvalidSignature";
831
+ readonly inputs: readonly [];
832
+ }, {
833
+ readonly type: "error";
834
+ readonly name: "ECDSAInvalidSignatureLength";
835
+ readonly inputs: readonly [{
836
+ readonly name: "length";
837
+ readonly type: "uint256";
838
+ readonly internalType: "uint256";
839
+ }];
840
+ }, {
841
+ readonly type: "error";
842
+ readonly name: "ECDSAInvalidSignatureS";
843
+ readonly inputs: readonly [{
844
+ readonly name: "s";
845
+ readonly type: "bytes32";
846
+ readonly internalType: "bytes32";
847
+ }];
848
+ }, {
849
+ readonly type: "error";
850
+ readonly name: "EmptyId";
851
+ readonly inputs: readonly [];
852
+ }, {
853
+ readonly type: "error";
854
+ readonly name: "IdMismatch";
855
+ readonly inputs: readonly [];
856
+ }, {
857
+ readonly type: "error";
858
+ readonly name: "InvalidShortString";
859
+ readonly inputs: readonly [];
860
+ }, {
861
+ readonly type: "error";
862
+ readonly name: "NotSponsor";
863
+ readonly inputs: readonly [];
864
+ }, {
865
+ readonly type: "error";
866
+ readonly name: "ReentrancyGuardReentrantCall";
867
+ readonly inputs: readonly [];
868
+ }, {
869
+ readonly type: "error";
870
+ readonly name: "SafeERC20FailedOperation";
871
+ readonly inputs: readonly [{
872
+ readonly name: "token";
873
+ readonly type: "address";
874
+ readonly internalType: "address";
875
+ }];
876
+ }, {
877
+ readonly type: "error";
878
+ readonly name: "SaltMismatch";
879
+ readonly inputs: readonly [];
880
+ }, {
881
+ readonly type: "error";
882
+ readonly name: "SecretMismatch";
883
+ readonly inputs: readonly [];
884
+ }, {
885
+ readonly type: "error";
886
+ readonly name: "StringTooLong";
887
+ readonly inputs: readonly [{
888
+ readonly name: "str";
889
+ readonly type: "string";
890
+ readonly internalType: "string";
891
+ }];
892
+ }, {
893
+ readonly type: "error";
894
+ readonly name: "ZeroAmount";
895
+ readonly inputs: readonly [];
896
+ }, {
897
+ readonly type: "error";
898
+ readonly name: "ZeroClaimAddress";
899
+ readonly inputs: readonly [];
900
+ }, {
901
+ readonly type: "error";
902
+ readonly name: "ZeroRecipient";
903
+ readonly inputs: readonly [];
904
+ }, {
905
+ readonly type: "error";
906
+ readonly name: "ZeroToken";
907
+ readonly inputs: readonly [];
908
+ }];
909
+
910
+ /**
911
+ * 일괄 수령(batch claim) ABI — **배포 바이트코드에서 검증한** as-built 기록.
912
+ *
913
+ * `src/infrastructure/safedrop_abi.json`(Foundry 산출물)에는 이 함수들이 없다.
914
+ * 반대로 openapi.json 설명이 말하는 `validatorNonceById`는 **string이 아니라
915
+ * bytes32(=keccak256(utf8(id)))** 를 받는다. 그래서 자동 생성 ABI를 믿지 않고
916
+ * 배포본(CROSS testnet 612044 `0x50911242D9EA1554297ad11eb634230C56ae769c`)의
917
+ * dispatcher 셀렉터로 직접 확인한 시그니처만 여기 둔다 (2026-07-30 검증):
918
+ *
919
+ * 3a5381b5 validator()
920
+ * aee5b003 validatorClaimDigest(address,string,uint256,uint256)
921
+ * dc4d9bff validatorNonceById(bytes32) ← id는 **해시**로 키잉
922
+ * a730b8c5 withdrawByValidator(address,string,uint256,uint256,uint256,bytes)
923
+ * 0d14a67d ValidatorSigExpired()
924
+ * dcf5a899 InvalidValidatorNonce()
925
+ *
926
+ * eth_call로 확인한 검증 순서: deadline → nonce → 서명(ECDSA).
927
+ * `maxCount`는 **서명 대상이 아니다** — 그래서 서명 1건으로 페이지네이션을 계속
928
+ * 재사용할 수 있다(openapi 설명과 일치). 온체인 상한은 없고 가스가 한계다.
929
+ *
930
+ * EIP-712 (배포본 `eip712Domain()`으로 확인):
931
+ * domain = { name: 'ONEpop', version: '1', chainId, verifyingContract: SafeDrop }
932
+ * type = ValidatorClaim(address recipient,string id,uint256 nonce,uint256 deadline)
933
+ * → digest는 `validatorClaimDigest()`가 온체인에서 그대로 돌려주므로, 로컬에서
934
+ * 재조립하지 말고 그 값을 읽어 쓴다(백엔드와의 불일치를 가스 전에 잡는다).
935
+ */
936
+ declare const SAFEDROP_VALIDATOR_ABI: readonly [{
937
+ readonly type: "function";
938
+ readonly name: "validator";
939
+ readonly stateMutability: "view";
940
+ readonly inputs: readonly [];
941
+ readonly outputs: readonly [{
942
+ readonly type: "address";
943
+ }];
944
+ }, {
945
+ readonly type: "function";
946
+ readonly name: "validatorClaimDigest";
947
+ readonly stateMutability: "view";
948
+ readonly inputs: readonly [{
949
+ readonly name: "recipient";
950
+ readonly type: "address";
951
+ }, {
952
+ readonly name: "id";
953
+ readonly type: "string";
954
+ }, {
955
+ readonly name: "nonce";
956
+ readonly type: "uint256";
957
+ }, {
958
+ readonly name: "deadline";
959
+ readonly type: "uint256";
960
+ }];
961
+ readonly outputs: readonly [{
962
+ readonly type: "bytes32";
963
+ }];
964
+ }, {
965
+ readonly type: "function";
966
+ readonly name: "validatorNonceById";
967
+ readonly stateMutability: "view";
968
+ readonly inputs: readonly [{
969
+ readonly name: "idHash";
970
+ readonly type: "bytes32";
971
+ }];
972
+ readonly outputs: readonly [{
973
+ readonly type: "uint256";
974
+ }];
975
+ }, {
976
+ readonly type: "function";
977
+ readonly name: "withdrawByValidator";
978
+ readonly stateMutability: "nonpayable";
979
+ readonly inputs: readonly [{
980
+ readonly name: "recipient";
981
+ readonly type: "address";
982
+ }, {
983
+ readonly name: "id";
984
+ readonly type: "string";
985
+ }, {
986
+ readonly name: "nonce";
987
+ readonly type: "uint256";
988
+ }, {
989
+ readonly name: "deadline";
990
+ readonly type: "uint256";
991
+ }, {
992
+ readonly name: "maxCount";
993
+ readonly type: "uint256";
994
+ }, {
995
+ readonly name: "signature";
996
+ readonly type: "bytes";
997
+ }];
998
+ readonly outputs: readonly [];
999
+ }, {
1000
+ readonly type: "function";
1001
+ readonly name: "liveDropCountById";
1002
+ readonly stateMutability: "view";
1003
+ readonly inputs: readonly [{
1004
+ readonly name: "id";
1005
+ readonly type: "string";
1006
+ }];
1007
+ readonly outputs: readonly [{
1008
+ readonly type: "uint256";
1009
+ }];
1010
+ }, {
1011
+ readonly type: "function";
1012
+ readonly name: "claimedRecipientOf";
1013
+ readonly stateMutability: "view";
1014
+ readonly inputs: readonly [{
1015
+ readonly name: "id";
1016
+ readonly type: "string";
1017
+ }];
1018
+ readonly outputs: readonly [{
1019
+ readonly type: "address";
1020
+ }];
1021
+ }, {
1022
+ readonly type: "error";
1023
+ readonly name: "ValidatorSigExpired";
1024
+ readonly inputs: readonly [];
1025
+ }, {
1026
+ readonly type: "error";
1027
+ readonly name: "InvalidValidatorNonce";
1028
+ readonly inputs: readonly [];
1029
+ }];
1030
+
1031
+ /**
1032
+ * cross-auth SIWE 로그인 클라이언트. createClaimWallet에 필요한 플랫폼 JWT를 얻는다.
1033
+ * 1) unsignedHash(chainId, address) → { hash, message }
1034
+ * 2) 앱이 지갑으로 message 서명(signMessage)
1035
+ * 3) siweToken(address, signature) → { token, refresh }
1036
+ *
1037
+ * 서명은 앱(wagmi/walletClient)이 수행 — 이 클라이언트는 HTTP만 담당한다.
1038
+ * domain은 cross-auth가 SIWE domain으로 사용(기본 window.location.origin).
1039
+ */
1040
+ interface CrossAuthClientOptions {
1041
+ /** 미지정 시 환경변수(VITE_/NEXT_PUBLIC_CROSS_AUTH_URL) 또는 dev 기본값. */
1042
+ baseUrl?: string;
1043
+ /** SIWE domain. 미지정 시 globalThis.location.origin. */
1044
+ domain?: string;
1045
+ fetchImpl?: typeof fetch;
1046
+ }
1047
+ declare class CrossAuthClient {
1048
+ private readonly baseUrl;
1049
+ private readonly domain;
1050
+ private readonly fetchImpl;
1051
+ constructor(options?: CrossAuthClientOptions);
1052
+ /** SIWE 서명 대상 메시지 발급. cross-auth 필드는 snake_case `chain_id`. */
1053
+ unsignedHash(chainId: number, address: string): Promise<{
1054
+ hash: string;
1055
+ message: string;
1056
+ }>;
1057
+ /** 서명 → 플랫폼 JWT 교환. */
1058
+ siweToken(address: string, signature: string): Promise<{
1059
+ token: string;
1060
+ refresh: string;
1061
+ }>;
1062
+ private post;
1063
+ }
1064
+
1065
+ interface CreateSafeDropClientOptions {
1066
+ /** SafeDrop 컨트랙트 주소. */
1067
+ contractAddress: Address;
1068
+ publicClient: PublicClient;
1069
+ /** approve/deposit/refund 서명용 연결 지갑. */
1070
+ walletClient: WalletClient;
1071
+ chain: Chain;
1072
+ /** withdraw 임시 지갑 client의 RPC transport. */
1073
+ transport?: Transport;
1074
+ /** withdraw gas/fee override (gas-abstraction). */
1075
+ withdrawFees?: ViemSafeDropChainAdapterOptions['withdrawFees'];
1076
+ /**
1077
+ * true면 EIP-2612 permit 예치 — approve tx가 사라지고 서명 1회 + tx 1회가 된다.
1078
+ * SafeDrop 배포본과 토큰 양쪽이 permit을 지원할 때만 켠다.
1079
+ */
1080
+ permit?: boolean;
1081
+ /** 수령 링크 base URL. */
1082
+ claimBaseUrl: string;
1083
+ /** one-pop-api 어댑터 옵션(baseUrl 미지정 시 환경변수). */
1084
+ api?: HttpSafeDropApiAdapterOptions;
1085
+ /** 직접 만든 SafeDropApiPort를 쓰려면 주입(mock/커스텀). */
1086
+ apiPort?: SafeDropApiPort;
1087
+ }
1088
+ /** viem + HTTP 어댑터를 조립해 SafeDrop을 반환하는 기본 진입점. */
1089
+ declare function createSafeDropClient(options: CreateSafeDropClientOptions): SafeDrop;
1090
+
1091
+ interface Pkce {
1092
+ verifier: string;
1093
+ challenge: string;
1094
+ method: 'S256';
1095
+ }
1096
+ /** code_verifier(43자) + S256 code_challenge 생성. */
1097
+ declare function generatePkce(): Promise<Pkce>;
1098
+ /** CSRF 방지용 state (base64url 22자). */
1099
+ declare function generateState(): string;
1100
+
1101
+ /**
1102
+ * X OAuth2 프록시 어댑터. 앱의 same-origin Next 라우트를 호출한다(one-pop-fe와 동일 계약).
1103
+ * POST {tokenPath} { clientId, redirectUri, code, verifier } → X 토큰 응답(access_token)
1104
+ * GET {mePath} Authorization: Bearer <token> → GET /2/users/me ({ data: { username } })
1105
+ *
1106
+ * 프록시가 grant_type/Basic auth 조립과 X API 응답 전달을 담당한다. 다르면 옵션으로 경로만 조정.
1107
+ */
1108
+ interface HttpXAuthAdapterOptions {
1109
+ /** 프록시 base URL. 기본 '' (same-origin 상대경로). */
1110
+ baseUrl?: string;
1111
+ /** 토큰 교환 프록시 경로. 기본 '/api/x/token'. */
1112
+ tokenPath?: string;
1113
+ /** 핸들 조회 프록시 경로. 기본 '/api/x/me'. */
1114
+ mePath?: string;
1115
+ fetchImpl?: typeof fetch;
1116
+ }
1117
+ declare class HttpXAuthAdapter implements XAuthPort {
1118
+ private readonly baseUrl;
1119
+ private readonly tokenPath;
1120
+ private readonly mePath;
1121
+ private readonly fetchImpl;
1122
+ constructor(options?: HttpXAuthAdapterOptions);
1123
+ exchangeCode(params: {
1124
+ clientId: string;
1125
+ redirectUri: string;
1126
+ code: string;
1127
+ codeVerifier: string;
1128
+ }): Promise<XTokenResult>;
1129
+ getHandle(accessToken: string): Promise<{
1130
+ handle: string;
1131
+ }>;
1132
+ private call;
1133
+ }
1134
+
1135
+ /** verifier/state 임시 보관. 기본은 sessionStorage 어댑터. */
1136
+ interface SessionStore {
1137
+ get(key: string): string | null;
1138
+ set(key: string, value: string): void;
1139
+ remove(key: string): void;
1140
+ }
1141
+ interface XAuthClientOptions {
1142
+ clientId: string;
1143
+ redirectUri: string;
1144
+ /** 기본 'tweet.read users.read offline.access' (GET /2/users/me + refresh token). */
1145
+ scope?: string;
1146
+ /** 기본 X authorize 엔드포인트. */
1147
+ authorizeUrl?: string;
1148
+ /** 토큰 교환/핸들 조회 프록시 어댑터. */
1149
+ port: XAuthPort;
1150
+ /** 기본 globalThis.sessionStorage 어댑터. */
1151
+ storage?: SessionStore;
1152
+ }
1153
+ /**
1154
+ * X OAuth2 PKCE 플로우. UI/리다이렉트는 앱이 담당한다:
1155
+ * const { authorizeUrl } = await xauth.start(); location.assign(authorizeUrl);
1156
+ * // 콜백에서:
1157
+ * const { oauth, handle } = await xauth.complete(location.href);
1158
+ * await safeDrop.retrieveClaimKey({ senderAddress, oauth });
1159
+ */
1160
+ declare class XAuthClient {
1161
+ private readonly opts;
1162
+ constructor(options: XAuthClientOptions);
1163
+ /** PKCE·state 생성·저장 후 X authorize URL 반환. 리다이렉트는 호출자 몫. */
1164
+ start(): Promise<{
1165
+ authorizeUrl: string;
1166
+ state: string;
1167
+ }>;
1168
+ /** 콜백 URL에서 code/state 추출 → state 검증 → 토큰 교환 → 핸들 조회. */
1169
+ complete(callbackUrl: string): Promise<{
1170
+ oauth: OAuthProof;
1171
+ handle: string;
1172
+ }>;
1173
+ }
1174
+
1175
+ export { type CreateSafeDropClientOptions, CrossAuthClient, type CrossAuthClientOptions, DEFAULT_POP_API_PATHS, HttpSafeDropApiAdapter, type HttpSafeDropApiAdapterOptions, HttpXAuthAdapter, type HttpXAuthAdapterOptions, type Pkce, type PopApiPaths, type PopEnvironment, SAFEDROP_ABI, SAFEDROP_VALIDATOR_ABI, type SessionStore, ViemClaimSignerAdapter, ViemCryptoAdapter, ViemSafeDropChainAdapter, type ViemSafeDropChainAdapterOptions, XAuthClient, type XAuthClientOptions, createSafeDropClient, generatePkce, generateState, getCrossAuthBaseUrl, getOnePopApiBaseUrl };