@nexus-cross/pop 1.3.10-beta.2 → 1.4.0-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.
@@ -1,6 +1,6 @@
1
1
  /** 0x-prefixed 주소. viem Address에 의존하지 않는 도메인 표현. */
2
2
  type Address = string;
3
- /** 0x-prefixed hex 문자열 (서명/salt/digest/해시 등). */
3
+ /** 0x-prefixed hex 문자열 (서명/digest/drop key/해시 등). */
4
4
  type Hex = string;
5
5
  /** 소셜 식별자 string (컨트랙트 `id`). 예: 'theo_13303'. */
6
6
  type Id = string;
@@ -28,7 +28,7 @@ interface DepositParams {
28
28
  token: Address;
29
29
  /** raw 토큰 수량 (wei-scale). BigInt 유지. */
30
30
  amount: bigint;
31
- /** 비밀 문구. 미지정 시 CryptoPort.randomSecret()로 생성. (expiry는 계약이 결정.) */
31
+ /** 비밀 문구. 미지정 시 CryptoPort.randomSecret()로 생성. */
32
32
  secret?: Secret;
33
33
  /**
34
34
  * 수령인에게 보여줄 메시지 (최대 140 runes). 컨트랙트에는 필드가 없고
@@ -38,7 +38,8 @@ interface DepositParams {
38
38
  /** 카드 디자인 id. 목록은 `listEnvelopes()` (GET /envelopes). */
39
39
  envelopeId?: string;
40
40
  }
41
- interface DepositResult {
41
+ interface UnmappedDepositResult {
42
+ readonly isMapped: false;
42
43
  /** 컨트랙트에 커밋된 임시 claim 지갑 주소 = 이 드롭의 키. */
43
44
  readonly claimAddress: Address;
44
45
  readonly secretHash: SecretHash;
@@ -46,7 +47,14 @@ interface DepositResult {
46
47
  readonly withdrawLink: string;
47
48
  readonly depositTxHash: Hex;
48
49
  }
50
+ interface MappedDepositResult {
51
+ readonly isMapped: true;
52
+ readonly depositTxHash: Hex;
53
+ }
54
+ type DepositResult = UnmappedDepositResult | MappedDepositResult;
49
55
  interface WithdrawParams {
56
+ /** 링크의 sender query 값 = 온체인 sponsor. */
57
+ sponsor: Address;
50
58
  /** 수령 주소 — 수령인 본인이 지정. 서명에 바인딩된다. */
51
59
  recipient: Address;
52
60
  /** X OAuth 검증 후 백엔드에서 받은 임시 claim 지갑 주소. drops() 조회 키. */
@@ -60,7 +68,9 @@ interface WithdrawResult {
60
68
  readonly txHash: Hex;
61
69
  }
62
70
  interface RefundParams {
63
- /** 환불할 드롭의 claimAddr. 만료 후 sponsor(msg.sender)만 호출 가능. */
71
+ /** 드롭 sponsor. */
72
+ sponsor: Address;
73
+ /** 환불할 드롭의 claimAddr. sponsor(msg.sender)만 호출 가능. */
64
74
  claimAddress: Address;
65
75
  }
66
76
  interface RefundResult {
@@ -71,6 +81,14 @@ interface BatchClaimParams {
71
81
  id: Id;
72
82
  /** 핸들 소유 증명용 X OAuth 토큰. 서명 발급의 전제. */
73
83
  oauth: OAuthProof;
84
+ /** anchor drop의 sponsor(링크 sender). */
85
+ sponsor: Address;
86
+ /** 첫 unmapped 드롭의 임시 claim 지갑 주소. */
87
+ claimAddress: Address;
88
+ /** 첫 드롭 링크 fragment의 secret. */
89
+ secret: Secret;
90
+ /** 첫 드롭의 임시 claim 개인키. */
91
+ claimKey: Hex;
74
92
  /**
75
93
  * 기대하는 수령 주소. 서명은 **SIWE 인증 주소**에 바인딩되므로, 다르면
76
94
  * `SIGN_FAILED`로 끊는다(다른 주소로 받으려면 그 주소로 SIWE 로그인).
@@ -81,11 +99,11 @@ interface BatchClaimParams {
81
99
  deadline?: bigint;
82
100
  /** deadline 자동 계산용 TTL(초). 기본 1800. */
83
101
  deadlineTtlSeconds?: bigint;
84
- /** tx 1건이 처리할 드롭 수(서명 대상 아님 — 페이지 크기). 기본 30. */
102
+ /** tx 한 건에 포함할 drop key 수. 기본 30. 호출마다 새 validator 서명을 받는다. */
85
103
  maxCount?: number;
86
104
  }
87
105
  interface BatchClaimResult {
88
- /** 페이지별 tx hash. 드롭이 maxCount 이하면 1건. */
106
+ /** 현재 batch 호출의 tx hash(호환을 위해 배열 유지). */
89
107
  readonly txHashes: readonly Hex[];
90
108
  /** 실제로 서명에 바인딩된 수령 주소. */
91
109
  readonly recipient: Address;
@@ -93,7 +111,7 @@ interface BatchClaimResult {
93
111
  readonly nonce: bigint;
94
112
  readonly deadline: bigint;
95
113
  }
96
- type SafeDropErrorCode = 'MISSING_SENDER' | 'MISSING_RECIPIENT' | 'MISSING_SECRET' | 'MISSING_CLAIM_KEY' | 'MISSING_CLAIM_ADDRESS' | 'INVALID_AMOUNT' | 'INVALID_TOKEN' | 'DROP_NOT_FOUND' | 'SECRET_MISMATCH' | 'SIGN_FAILED' | 'CHAIN_ERROR' | 'API_ERROR' | 'INVALID_PARAM' | 'RATE_LIMITED' | 'INVALID_OAUTH_TOKEN' | 'UNAUTHORIZED' | 'WALLET_NOT_FOUND' | 'SEND_BLOCKED' | 'ENVELOPE_NOT_FOUND' | 'PENDING_LIMIT_EXCEEDED' | 'X_CONNECTION_NOT_FOUND';
114
+ type SafeDropErrorCode = 'MISSING_SENDER' | 'MISSING_RECIPIENT' | 'MISSING_SECRET' | 'MISSING_CLAIM_KEY' | 'MISSING_CLAIM_ADDRESS' | 'INVALID_AMOUNT' | 'INVALID_TOKEN' | 'DROP_NOT_FOUND' | 'SECRET_MISMATCH' | 'SIGN_FAILED' | 'CHAIN_ERROR' | 'API_ERROR' | 'INVALID_PARAM' | 'RATE_LIMITED' | 'INVALID_OAUTH_TOKEN' | 'UNAUTHORIZED' | 'WALLET_NOT_FOUND' | 'SEND_BLOCKED' | 'ENVELOPE_NOT_FOUND' | 'PENDING_LIMIT_EXCEEDED' | 'IDENTIFIER_NOT_MAPPED' | 'X_CONNECTION_NOT_FOUND';
97
115
  declare class SafeDropError extends Error {
98
116
  readonly code: SafeDropErrorCode;
99
117
  readonly details?: Record<string, unknown>;
@@ -108,6 +126,9 @@ interface XConnection {
108
126
  readonly profileImageUrl: string;
109
127
  /** SIWE 인증 주소. 본문으로 고를 수 없다. */
110
128
  readonly walletAddress: Address;
129
+ readonly revealYou: boolean;
130
+ readonly onchainMapped: boolean;
131
+ readonly mappedRecipient: Address | null;
111
132
  }
112
133
  /** 드롭을 보낸 sponsor. X 연결이 없으면 handle/displayName/profileImageUrl은 빈 문자열. */
113
134
  interface DropSender {
@@ -118,6 +139,10 @@ interface DropSender {
118
139
  }
119
140
  /** GET /drops의 개별 항목. claimAddress로 개별 수령(withdraw)을 진행한다. */
120
141
  interface PendingDrop {
142
+ /** 백엔드 drop id. feedback 등록에 사용한다. */
143
+ readonly id: number;
144
+ /** 현재 컨트랙트의 bytes32 drop key. */
145
+ readonly dropKey: Hex;
121
146
  readonly claimAddress: Address;
122
147
  readonly token: Address;
123
148
  /** raw 토큰 수량 (wei-scale). */
@@ -138,6 +163,8 @@ interface DropInbox {
138
163
  readonly totalAmount: bigint;
139
164
  /** 첫 수령은 개별 claim만 허용 — 일괄 수령 CTA 게이트. */
140
165
  readonly hasClaimedBefore: boolean;
166
+ readonly mappedRecipient: Address | null;
167
+ readonly pendingChangeTo: Address | null;
141
168
  }
142
169
  /** GET /envelopes — 카드 디자인. 공개 엔드포인트. */
143
170
  interface Envelope {
@@ -147,30 +174,50 @@ interface Envelope {
147
174
  readonly badge: string;
148
175
  readonly sortOrder: number;
149
176
  }
150
- /** GET /leaderboards — identifier별 pending 잔액 상위(최대 10). 공개 엔드포인트. */
177
+ /** GET /leaderboards — identifier별 pending 잔액. */
151
178
  interface LeaderboardEntry {
152
179
  readonly identifier: string;
153
180
  /** 수령 가능(pending) 합계 (wei-scale). */
154
181
  readonly balance: bigint;
155
182
  /** 최근 Deposited 금액 (wei-scale). */
156
183
  readonly lastDepositAmount: bigint;
184
+ readonly rank: number;
185
+ readonly previousRank: number | null;
186
+ readonly profileImageUrl: string;
187
+ }
188
+ interface LeaderboardPage {
189
+ readonly items: readonly LeaderboardEntry[];
190
+ readonly page: number;
191
+ readonly pageSize: number;
192
+ readonly total: number;
193
+ }
194
+ interface MyLeaderboardEntry extends Omit<LeaderboardEntry, 'rank'> {
195
+ readonly rank: number | null;
196
+ }
197
+ type HistoryType = 'sent' | 'received';
198
+ interface HistoryParty {
199
+ readonly address: Address;
200
+ readonly handle: string;
201
+ readonly displayName: string;
202
+ readonly profileImageUrl: string;
157
203
  }
158
- type PopEventName = 'Deposited' | 'Withdrawn' | 'Refunded' | 'BatchWithdrawn';
159
- /** GET /histories 항목. 이벤트가 담지 않는 주소는 null. */
204
+ /** GET /histories의 drop 중심 항목. */
160
205
  interface HistoryEntry {
161
- readonly eventName: PopEventName | (string & {});
162
- readonly txHash: Hex;
163
- readonly blockNumber: number;
164
- readonly logIndex: number;
165
- readonly contractAddress: Address;
166
- readonly fromAddress: Address | null;
167
- readonly toAddress: Address | null;
168
- readonly tempTo: Address | null;
169
- readonly identifier: string;
170
- /** wei-scale. */
206
+ readonly id: number;
207
+ readonly type: HistoryType;
208
+ readonly status: string;
209
+ readonly token: Address;
171
210
  readonly amount: bigint;
172
- readonly createdAt: string;
173
- readonly payload?: Record<string, unknown>;
211
+ readonly claimAddress: Address;
212
+ readonly depositTxHash: Hex;
213
+ readonly depositedAt: string;
214
+ readonly resolvedTxHash: Hex | null;
215
+ readonly resolvedAt: string | null;
216
+ readonly message: string;
217
+ readonly feedback: string | null;
218
+ readonly envelopeId: string;
219
+ readonly sender: HistoryParty;
220
+ readonly receiver: HistoryParty;
174
221
  }
175
222
  interface HistoryPage {
176
223
  readonly items: readonly HistoryEntry[];
@@ -182,8 +229,7 @@ interface HistoryPage {
182
229
  /**
183
230
  * POST /batch-claim-signature 결과 — EIP-712 ValidatorClaim 서명.
184
231
  * recipient는 항상 Bearer 토큰의 SIWE 주소다(본문으로 못 고른다).
185
- * 같은 id의 live 드롭이 모두 빠질 때까지 페이지네이션된 온체인 호출에
186
- * **재사용**한다 — 페이지마다 다시 발급받지 않는다.
232
+ * 서명은 성공한 온체인 호출 1건마다 nonce와 함께 소비된다.
187
233
  */
188
234
  interface BatchClaimSignature {
189
235
  readonly id: Id;
@@ -192,6 +238,15 @@ interface BatchClaimSignature {
192
238
  readonly deadline: bigint;
193
239
  readonly signature: Hex;
194
240
  }
241
+ interface RecipientSignature {
242
+ readonly id: Id;
243
+ readonly nonce: bigint;
244
+ readonly deadline: bigint;
245
+ readonly signature: Hex;
246
+ }
247
+ interface RecipientChangeSignature extends RecipientSignature {
248
+ readonly newRecipient: Address;
249
+ }
195
250
 
196
251
  /**
197
252
  * 순수 계산이 아니라 외부 구현(해시 라이브러리/CSPRNG)이 필요한 암호 연산.
@@ -229,27 +284,30 @@ interface SafeDropApiPort {
229
284
  createClaimWallet(params: {
230
285
  sender: Address;
231
286
  recipient: SocialIdentifier;
232
- /** 수령인에게 보여줄 메시지 (≤140 runes, 백엔드 저장 전용). */
233
- message?: string;
234
- /** 카드 디자인 id (GET /envelopes). */
235
- envelopeId?: string;
236
287
  }): Promise<{
237
288
  claimAddress: Address;
289
+ id: Id;
290
+ isMapped: boolean;
238
291
  }>;
292
+ /** Associate off-chain card metadata after the deposit transaction is broadcast. */
293
+ recordDropMetadata?(params: {
294
+ txHash: Hex;
295
+ message?: string;
296
+ envelopeId?: string;
297
+ }): Promise<void>;
239
298
  /**
240
299
  * Withdraw: X OAuth 검증 후 복호화된 임시 claim 개인키 반환 (point of return).
241
- * dropId가 아니라 (sender_address + OAuth 토큰 소유자의 identifier) 조합으로
242
- * 해당하는 최신 pending 지갑 키를 찾는다 — one-pop-api /wallets/private-key.
243
- *
244
- * ⚠️ 한 (sender, identifier)에 pending 드롭이 여러 개 있을 수 있다(백엔드가
245
- * 중복 제한을 풀었다). 이 엔드포인트는 그중 **최신 1건**만 돌려주고 특정
246
- * claimAddress를 고르는 파라미터가 없다 — 같은 sender가 보낸 여러 드롭은
247
- * 링크마다 순차로 수령해야 한다. 전체 목록은 `listDrops()`로 본다.
300
+ * claimAddress로 특정 pending 지갑을 선택하고 OAuth 토큰으로 handle 소유권을
301
+ * 증명한다 — one-pop-api /wallets/private-key.
248
302
  */
249
303
  retrieveClaimKey(params: {
304
+ claimAddress: Address;
250
305
  senderAddress: Address;
251
306
  oauth: OAuthProof;
252
307
  }): Promise<{
308
+ isMapped: true;
309
+ } | {
310
+ isMapped: false;
253
311
  claimKey: Hex;
254
312
  claimAddress: Address;
255
313
  }>;
@@ -261,13 +319,20 @@ interface SafeDropApiPort {
261
319
  listEnvelopes?(params?: {
262
320
  locale?: string;
263
321
  }): Promise<readonly Envelope[]>;
264
- /** GET /leaderboards — 토큰별 pending 잔액 상위. 공개(인증 불필요). */
322
+ /** GET /leaderboards — 토큰별 pending 잔액. 공개(인증 불필요). */
265
323
  getLeaderboard?(params: {
266
324
  token: Address;
267
- }): Promise<readonly LeaderboardEntry[]>;
325
+ page?: number;
326
+ pageSize?: number;
327
+ identifier?: string;
328
+ }): Promise<LeaderboardPage>;
329
+ getMyLeaderboardEntry?(params: {
330
+ token: Address;
331
+ }): Promise<MyLeaderboardEntry>;
268
332
  /** GET /histories — 내가 sender이거나 최종 수령인인 온체인 이벤트. Bearer JWT. */
269
- listHistories?(params?: {
270
- event?: PopEventName;
333
+ listHistories?(params: {
334
+ type: HistoryType;
335
+ token?: Address;
271
336
  /** 1-based (기본 1). */
272
337
  page?: number;
273
338
  /** 기본 20, 최대 100. */
@@ -281,6 +346,25 @@ interface SafeDropApiPort {
281
346
  }): Promise<XConnection>;
282
347
  /** DELETE /x-connections — 연결 해제. 이미 없으면 조용히 성공(idempotent). */
283
348
  disconnectX?(): Promise<void>;
349
+ submitFeedback?(params: {
350
+ dropId: number;
351
+ message: string;
352
+ }): Promise<string>;
353
+ setRevealYou?(params: {
354
+ revealYou: boolean;
355
+ }): Promise<boolean>;
356
+ requestRecipientChangeSignature?(params: {
357
+ id: Id;
358
+ oauth: OAuthProof;
359
+ nonce: bigint;
360
+ deadline: bigint;
361
+ }): Promise<RecipientChangeSignature>;
362
+ requestRecipientResetSignature?(params: {
363
+ id: Id;
364
+ oauth: OAuthProof;
365
+ nonce: bigint;
366
+ deadline: bigint;
367
+ }): Promise<RecipientSignature>;
284
368
  /**
285
369
  * POST /batch-claim-signature — 일괄 수령용 EIP-712 ValidatorClaim 서명.
286
370
  * nonce/deadline은 호출자가 정한다. nonce는 컨트랙트
@@ -296,25 +380,20 @@ interface SafeDropApiPort {
296
380
  }): Promise<BatchClaimSignature>;
297
381
  }
298
382
 
299
- /**
300
- * drops(claimAddr) 결과 매핑.
301
- *
302
- * ⚠️ 배포본마다 `drops`의 반환 필드 수가 다르다(permit 배포본은 5개 —
303
- * sponsor/amount/secretHash/salt/id). 그래서 `token`·`expiry`는 **optional**이다:
304
- * - `token` — 5필드 배포본에서는 에스크로의 `token()`으로 채운다(단일 토큰 고정).
305
- * - `expiry` — 5필드 배포본은 노출하지 않는다 → `undefined`. 만료 판정에 쓰기 전에
306
- * 존재 여부를 확인해야 한다(없다고 만료가 아니라, 알 수 없다는 뜻).
307
- */
308
- interface DropState {
309
- claimAddress: Address;
383
+ /** Current ONEpop drop record, keyed by bytes32 rather than claim wallet. */
384
+ interface OnePopDrop {
385
+ dropKey: Hex;
310
386
  sponsor: Address;
311
- token?: Address;
312
387
  amount: bigint;
313
- expiry?: number;
388
+ claimAddress: Address;
389
+ recipient: Address;
314
390
  secretHash: SecretHash;
315
- salt: Hex;
316
391
  id: Id;
317
392
  }
393
+ interface DropState extends OnePopDrop {
394
+ /** ONEpop escrow is single-token; token() is contract-wide. */
395
+ token: Address;
396
+ }
318
397
  /**
319
398
  * SafeDrop 컨트랙트 상호작용. 어댑터는 자신의 컨트랙트 주소를 알고 있으므로
320
399
  * approve의 spender 등은 받지 않는다. 쓰기는 receipt 확인 후 tx hash 반환.
@@ -322,101 +401,124 @@ interface DropState {
322
401
  * ABI: src/infrastructure/safedrop_abi.json.
323
402
  */
324
403
  interface SafeDropChainPort {
325
- /** drops(claimAddr). 없으면 null. */
326
- getDrop(claimAddress: Address): Promise<DropState | null>;
327
- /** claimDigest(recipient, id, salt) — 서명 대상 bytes32. */
404
+ getDropByKey(dropKey: Hex): Promise<OnePopDrop | null>;
405
+ getDropKeyByClaimAddress(claimAddress: Address, sponsor: Address): Promise<Hex | null>;
406
+ getClaimedRecipient(params: {
407
+ id: Id;
408
+ }): Promise<Address>;
409
+ getPendingDropsById(params: {
410
+ id: Id;
411
+ }): Promise<readonly OnePopDrop[]>;
412
+ getPendingDropsByRecipient(params: {
413
+ recipient: Address;
414
+ }): Promise<readonly OnePopDrop[]>;
415
+ getPendingDropsBySponsor(params: {
416
+ sponsor: Address;
417
+ }): Promise<readonly OnePopDrop[]>;
418
+ /** activeDropOf(claimAddr) → drops(dropKey). 없으면 null. */
419
+ getDrop(claimAddress: Address, sponsor: Address): Promise<DropState | null>;
420
+ /** claimDigest(recipient, id, dropKey) — 서명 대상 bytes32. */
328
421
  getClaimDigest(params: {
329
422
  recipient: Address;
330
423
  id: Id;
331
- salt: Hex;
332
- }): Promise<Hex>;
333
- /** ERC20 approve (spender = SafeDrop 컨트랙트). 연결된 지갑이 서명. */
334
- approve(params: {
335
- token: Address;
336
- amount: bigint;
424
+ dropKey: Hex;
337
425
  }): Promise<Hex>;
338
- /** deposit(claimAddr, token, amount, id, secretHash). sponsor = msg.sender. */
339
- deposit(params: {
426
+ /**
427
+ * EIP-2612 permit 예치 — 현재 ONEpop deposit의 유일한 형태다.
428
+ * 서명(typed data)·deadline·v/r/s는 전부 어댑터 내부 관심사다.
429
+ */
430
+ depositWithPermit(params: {
340
431
  claimAddress: Address;
341
432
  token: Address;
342
433
  amount: bigint;
343
434
  id: Id;
344
435
  secretHash: SecretHash;
436
+ onSubmitted?: (txHash: Hex) => void | Promise<void>;
345
437
  }): Promise<{
346
438
  txHash: Hex;
347
439
  }>;
348
- /**
349
- * EIP-2612 permit 예치 — approve tx 없이 서명 1회 + tx 1회로 끝낸다.
350
- * permit 예치를 지원하는 배포본에서만 구현되는 optional 경로: 존재하면
351
- * DepositUseCase가 approve+deposit 대신 이걸 쓴다.
352
- * 서명(typed data)·deadline·v/r/s는 전부 어댑터 내부 관심사다.
353
- */
354
- depositWithPermit?(params: {
355
- claimAddress: Address;
440
+ depositMapped(params: {
356
441
  token: Address;
357
442
  amount: bigint;
358
443
  id: Id;
359
- secretHash: SecretHash;
444
+ onSubmitted?: (txHash: Hex) => void | Promise<void>;
360
445
  }): Promise<{
361
446
  txHash: Hex;
362
447
  }>;
363
- /**
364
- * withdraw(recipient, id, salt, signature, secret). claimAddr는 서명 recover로
365
- * 도출. tx는 claimKey 임시 지갑이 직접 전송 — estimateGas 없이 고정 gas +
366
- * dynamic fee(type-2)로 보내 컨트랙트 gas-abstraction 대납을 받는다.
367
- */
368
- withdraw(params: {
448
+ withdrawUnmapped(params: {
369
449
  claimKey: Hex;
370
450
  recipient: Address;
371
451
  id: Id;
372
- salt: Hex;
373
- signature: Hex;
452
+ dropKey: Hex;
374
453
  secret: Secret;
454
+ signature?: Hex;
455
+ onSubmitted?: (txHash: Hex) => void | Promise<void>;
375
456
  }): Promise<Hex>;
376
- /** refund(claimAddr). 만료 후 sponsor(msg.sender)만. */
377
- refund(params: {
378
- claimAddress: Address;
457
+ withdrawMapped(params: {
458
+ dropKey: Hex;
459
+ onSubmitted?: (txHash: Hex) => void | Promise<void>;
379
460
  }): Promise<Hex>;
380
- /** validatorNonceById(keccak256(utf8(id))). id 해싱은 어댑터 책임. */
381
- getValidatorNonce?(params: {
382
- id: Id;
383
- }): Promise<bigint>;
384
- /**
385
- * validatorClaimDigest(recipient, id, nonce, deadline) — 온체인 EIP-712 다이제스트.
386
- * 로컬 재조립 대신 이 값을 읽어 백엔드 서명을 검증한다.
387
- */
388
- getValidatorClaimDigest?(params: {
461
+ batchWithdrawMapped(params: {
462
+ count: number;
463
+ }): Promise<Hex>;
464
+ batchWithdrawMappedByKeys(params: {
465
+ dropKeys: readonly Hex[];
466
+ }): Promise<Hex>;
467
+ withdrawUnmappedBatchByKeys(params: {
468
+ claimKey: Hex;
389
469
  recipient: Address;
390
470
  id: Id;
471
+ anchorDropKey: Hex;
472
+ secret: Secret;
391
473
  nonce: bigint;
392
474
  deadline: bigint;
475
+ dropKeys: readonly Hex[];
476
+ validatorSignature: Hex;
393
477
  }): Promise<Hex>;
394
- /** validator() — 서명자여야 하는 주소. 백엔드 서명 검증의 기준값. */
395
- getValidator?(): Promise<Address>;
396
- /** liveDropCountById(id) — 남은 수령 대기 건수(페이지네이션 종료 조건). */
397
- getLiveDropCount?(params: {
478
+ refundByKey(params: {
479
+ dropKey: Hex;
480
+ }): Promise<Hex>;
481
+ getChangeNonce(params: {
398
482
  id: Id;
399
483
  }): Promise<bigint>;
400
- /**
401
- * claimedRecipientOf(id) — 이 id가 **개별 수령(secret+OAuth)으로 확정한** 수령 주소.
402
- * 미수령 id는 zero. 일괄 수령의 목적지를 온체인 값으로 교차 검증하는 데 쓴다.
403
- */
404
- getClaimedRecipient?(params: {
484
+ getPendingRecipientChange(params: {
405
485
  id: Id;
406
486
  }): Promise<Address>;
487
+ requestRecipientChange(params: {
488
+ id: Id;
489
+ newRecipient: Address;
490
+ }): Promise<Hex>;
491
+ completeRecipientChange(params: {
492
+ id: Id;
493
+ nonce: bigint;
494
+ deadline: bigint;
495
+ signature: Hex;
496
+ }): Promise<Hex>;
497
+ cancelRecipientChange(params: {
498
+ id: Id;
499
+ }): Promise<Hex>;
500
+ resetRecipient(params: {
501
+ id: Id;
502
+ nonce: bigint;
503
+ deadline: bigint;
504
+ signature: Hex;
505
+ }): Promise<Hex>;
506
+ /** validatorNonceById(keccak256(utf8(id))). id 해싱은 어댑터 책임. */
507
+ getValidatorNonce?(params: {
508
+ id: Id;
509
+ }): Promise<bigint>;
407
510
  /**
408
- * withdrawByValidator(recipient, id, nonce, deadline, maxCount, signature).
409
- * tx는 **수령인 본인 지갑**이 보낸다(컨트랙트가 msg.sender와 서명의 recipient를
410
- * 대조). `maxCount`는 서명 대상이 아니라 페이지 크기다 — 같은 서명을 재사용한다.
511
+ * validatorClaimDigest(recipient, id, nonce, deadline) — 온체인 EIP-712 다이제스트.
512
+ * 로컬 재조립 대신 이 값을 읽어 백엔드 서명을 검증한다.
411
513
  */
412
- withdrawByValidator?(params: {
514
+ getValidatorClaimDigest?(params: {
413
515
  recipient: Address;
414
516
  id: Id;
415
517
  nonce: bigint;
416
518
  deadline: bigint;
417
- maxCount: number;
418
- signature: Hex;
419
519
  }): Promise<Hex>;
520
+ /** validator() — 서명자여야 하는 주소. 백엔드 서명 검증의 기준값. */
521
+ getValidator?(): Promise<Address>;
420
522
  }
421
523
 
422
524
  /**
@@ -438,7 +540,8 @@ interface ClaimSignerPort {
438
540
  * { claimBaseUrl },
439
541
  * { api, chain, signer, crypto },
440
542
  * );
441
- * const { withdrawLink, claimAddress } = await safeDrop.deposit({ ... });
543
+ * const result = await safeDrop.deposit({ ... });
544
+ * if (!result.isMapped) sendLink(result.withdrawLink);
442
545
  *
443
546
  * viem/HTTP 어댑터를 자동 조립하려면 `@nexus-cross/pop/adapters`의
444
547
  * createSafeDropClient를 사용한다. (도메인/컨트랙트 주소는 chain 어댑터가 안다.)
@@ -459,16 +562,37 @@ interface SafeDrop {
459
562
  deposit(params: DepositParams): Promise<DepositResult>;
460
563
  /** X OAuth 검증 후 (sender_address + 토큰 소유자)로 임시 claim 키/주소를 받는다 (point of return). */
461
564
  retrieveClaimKey(params: {
565
+ claimAddress: Address;
462
566
  senderAddress: Address;
463
567
  oauth: OAuthProof;
464
568
  }): Promise<{
569
+ isMapped: true;
570
+ } | {
571
+ isMapped: false;
465
572
  claimKey: Hex;
466
573
  claimAddress: Address;
467
574
  }>;
468
575
  withdraw(params: WithdrawParams): Promise<WithdrawResult>;
469
576
  refund(params: RefundParams): Promise<RefundResult>;
470
- /** 온체인 드롭 상태 (drops(claimAddr)). 없으면 null. */
471
- getDrop(claimAddress: Address): Promise<DropState | null>;
577
+ /** activeDropOf(claimAddr)로 조회한 현재 온체인 드롭. */
578
+ getDrop(claimAddress: Address, sponsor: Address): Promise<DropState | null>;
579
+ getDropByKey(dropKey: Hex): Promise<OnePopDrop | null>;
580
+ getDropKeyByClaimAddress(claimAddress: Address, sponsor: Address): Promise<Hex | null>;
581
+ getClaimedRecipient(id: Id): Promise<Address>;
582
+ getPendingDropsById(id: Id): Promise<readonly OnePopDrop[]>;
583
+ getPendingDropsByRecipient(recipient: Address): Promise<readonly OnePopDrop[]>;
584
+ getPendingDropsBySponsor(sponsor: Address): Promise<readonly OnePopDrop[]>;
585
+ withdrawUnmapped(params: Parameters<SafeDropChainPort['withdrawUnmapped']>[0]): Promise<Hex>;
586
+ withdrawMapped(params: Parameters<SafeDropChainPort['withdrawMapped']>[0]): Promise<Hex>;
587
+ batchWithdrawMapped(count: number): Promise<Hex>;
588
+ batchWithdrawMappedByKeys(dropKeys: readonly Hex[]): Promise<Hex>;
589
+ refundByKey(dropKey: Hex): Promise<Hex>;
590
+ getChangeNonce(id: Id): Promise<bigint>;
591
+ getPendingRecipientChange(id: Id): Promise<Address>;
592
+ requestRecipientChange(id: Id, newRecipient: Address): Promise<Hex>;
593
+ completeRecipientChange(params: Parameters<SafeDropChainPort['completeRecipientChange']>[0]): Promise<Hex>;
594
+ cancelRecipientChange(id: Id): Promise<Hex>;
595
+ resetRecipient(params: Parameters<SafeDropChainPort['resetRecipient']>[0]): Promise<Hex>;
472
596
  /** 내게 온 수령 대기 목록. Bearer JWT + 활성 X 연결 필요. */
473
597
  listDrops(params?: {
474
598
  token?: Address;
@@ -480,10 +604,17 @@ interface SafeDrop {
480
604
  /** 토큰별 pending 잔액 상위 (공개). */
481
605
  getLeaderboard(params: {
482
606
  token: Address;
483
- }): Promise<readonly LeaderboardEntry[]>;
484
- /** 내 온체인 이벤트 히스토리. Bearer JWT 필요. */
485
- listHistories(params?: {
486
- event?: PopEventName;
607
+ page?: number;
608
+ pageSize?: number;
609
+ identifier?: string;
610
+ }): Promise<LeaderboardPage>;
611
+ getMyLeaderboardEntry(params: {
612
+ token: Address;
613
+ }): Promise<MyLeaderboardEntry>;
614
+ /** sent/received 드롭 히스토리. Bearer JWT 필요. */
615
+ listHistories(params: {
616
+ type: HistoryType;
617
+ token?: Address;
487
618
  page?: number;
488
619
  pageSize?: number;
489
620
  }): Promise<HistoryPage>;
@@ -495,9 +626,26 @@ interface SafeDrop {
495
626
  }): Promise<XConnection>;
496
627
  /** X 연결 해제 (idempotent). */
497
628
  disconnectX(): Promise<void>;
629
+ submitFeedback(params: {
630
+ dropId: number;
631
+ message: string;
632
+ }): Promise<string>;
633
+ setRevealYou(revealYou: boolean): Promise<boolean>;
634
+ requestRecipientChangeSignature(params: {
635
+ id: Id;
636
+ oauth: OAuthProof;
637
+ nonce: bigint;
638
+ deadline: bigint;
639
+ }): Promise<RecipientChangeSignature>;
640
+ requestRecipientResetSignature(params: {
641
+ id: Id;
642
+ oauth: OAuthProof;
643
+ nonce: bigint;
644
+ deadline: bigint;
645
+ }): Promise<RecipientSignature>;
498
646
  /**
499
- * 일괄 수령 — nonce 조회 → 백엔드 서명 → **가스 전 서명 검증** → 전량 회수까지
500
- * 한 번에. tx는 연결된 수령인 지갑이 보낸다(secret 불필요).
647
+ * anchor drop의 secret/claim key와 validator 서명을 함께 사용해 현재 pending key를
648
+ * 한 번에 수령한다.
501
649
  */
502
650
  batchClaim(params: BatchClaimParams): Promise<BatchClaimResult>;
503
651
  /**
@@ -513,4 +661,4 @@ interface SafeDrop {
513
661
  }
514
662
  declare function createSafeDrop(config: SafeDropConfig, deps: SafeDropDeps): SafeDrop;
515
663
 
516
- export { type Address as A, type BatchClaimParams as B, type CryptoPort as C, type DepositParams as D, type Envelope as E, type Hex as H, type Id as I, type LeaderboardEntry as L, type OAuthProof as O, type PendingDrop as P, type RefundParams as R, type SafeDropChainPort as S, type WithdrawParams as W, type XConnection as X, type SafeDropApiPort as a, type DepositResult as b, type BatchClaimResult as c, type ClaimSignerPort as d, type WithdrawResult as e, type RefundResult as f, type Secret as g, type BatchClaimSignature as h, type DropInbox as i, type DropSender as j, type DropState as k, type HistoryEntry as l, type HistoryPage as m, type PopEventName as n, type SafeDrop as o, type SafeDropConfig as p, type SafeDropDeps as q, SafeDropError as r, type SafeDropErrorCode as s, type SecretHash as t, type SocialIdentifier as u, type SocialProvider as v, createSafeDrop as w };
664
+ export { type Address as A, type BatchClaimParams as B, type CryptoPort as C, type DepositParams as D, type Envelope as E, type SocialIdentifier as F, type SocialProvider as G, type Hex as H, type Id as I, createSafeDrop as J, type LeaderboardEntry as L, type MappedDepositResult as M, type OAuthProof as O, type PendingDrop as P, type RefundParams as R, type SafeDropChainPort as S, type UnmappedDepositResult as U, type WithdrawParams as W, type XConnection as X, type SafeDropApiPort as a, type DepositResult as b, type BatchClaimResult as c, type ClaimSignerPort as d, type WithdrawResult as e, type RefundResult as f, type Secret as g, type BatchClaimSignature as h, type DropInbox as i, type DropSender as j, type DropState as k, type HistoryEntry as l, type HistoryPage as m, type HistoryParty as n, type HistoryType as o, type LeaderboardPage as p, type MyLeaderboardEntry as q, type OnePopDrop as r, type RecipientChangeSignature as s, type RecipientSignature as t, type SafeDrop as u, type SafeDropConfig as v, type SafeDropDeps as w, SafeDropError as x, type SafeDropErrorCode as y, type SecretHash as z };