@nexus-cross/pop 1.4.0-beta.4 → 1.4.0-beta.6

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/AGENTS.md CHANGED
@@ -126,11 +126,11 @@ await safeDrop.withdraw({ recipient: myAddress, sponsor: sender!, claimAddress,
126
126
  ```ts
127
127
  await safeDrop.connectX({ oauth }); // required once before listDrops
128
128
  const conn = await safeDrop.getXConnection(); // null when not connected
129
- const inbox = await safeDrop.listDrops(); // { items, count, totalAmount, hasClaimedBefore }
129
+ const inbox = await safeDrop.listDrops({ token: ERC20_ADDRESS });
130
130
  await safeDrop.rejectDrops(inbox.items.slice(0, 1).map((drop) => drop.id));
131
- const rejected = await safeDrop.listRejectedDrops(); // hidden pending drops
131
+ const rejected = inbox.items.filter((drop) => drop.rejected); // flagged, excluded from totals
132
132
  const top = await safeDrop.getLeaderboard({ token: ERC20_ADDRESS, page: 1, pageSize: 10 });
133
- const page = await safeDrop.listHistories({ type: 'received', page: 1, pageSize: 20 });
133
+ const page = await safeDrop.listHistories({ type: 'received', status: 'pending', rejected: false });
134
134
  await safeDrop.disconnectX();
135
135
  ```
136
136
 
@@ -225,7 +225,6 @@ The SDK does not wrap it — use `EventSource` directly. Delivery is best-effort
225
225
  | `getDrop` | `activeDropOf(claimAddr)` + `drops(dropKey)` | — |
226
226
  | `listDrops` | `GET /drops` | JWT + active X connection |
227
227
  | `rejectDrops` | `POST /drops/reject` | JWT + active X connection |
228
- | `listRejectedDrops` | `GET /drops/rejected` | JWT + active X connection |
229
228
  | `listEnvelopes` | `GET /envelopes` | public |
230
229
  | `getLeaderboard` | `GET /leaderboards?token=` | public |
231
230
  | `listHistories` | `GET /histories` | JWT |
@@ -242,6 +241,7 @@ Everything rejects with `SafeDropError` — branch on `err.code`, never on the m
242
241
  | `UNAUTHORIZED` | no/expired SIWE JWT → re-run the SIWE login |
243
242
  | `INVALID_OAUTH_TOKEN` | X token missing `tweet.read`+`users.read`, or app-only → re-auth the user |
244
243
  | `X_CONNECTION_NOT_FOUND` | call `connectX()` first (also returned by `listDrops`) |
244
+ | `X_ALREADY_CONNECTED` | disconnect the active wallet before connecting a different wallet |
245
245
  | `WALLET_NOT_FOUND` | no pending claim wallet for that (sender, handle) — already claimed or refunded |
246
246
  | `PENDING_LIMIT_EXCEEDED` | too many pending drops for this pair → ask the user to wait/claim |
247
247
  | `SEND_BLOCKED` | sender blocked by the backend → surface, do not retry |
@@ -256,7 +256,7 @@ Everything rejects with `SafeDropError` — branch on `err.code`, never on the m
256
256
  ## 9. Common mistakes
257
257
 
258
258
  - Converting `amount` to `Number` for display math → silent precision loss above ~0.009 ETH in wei.
259
- - Calling `listDrops()` before `connectX()` → `X_CONNECTION_NOT_FOUND`.
259
+ - Calling `listDrops({ token })` before `connectX()` → `X_CONNECTION_NOT_FOUND`.
260
260
  - Passing the claim `secret` through a query parameter or logging it.
261
261
  - Building the claim link by hand instead of using the returned `withdrawLink` /
262
262
  `buildWithdrawLink` (the `#fragment` placement is load-bearing).
package/README.md CHANGED
@@ -153,18 +153,23 @@ await safeDrop.disconnectX(); // idempotent
153
153
  // 내게 온 수령 대기 목록 (Bearer JWT + 활성 X 연결)
154
154
  const inbox = await safeDrop.listDrops({ token: '0x…ERC20' });
155
155
  // { items, count, totalAmount, hasClaimedBefore, mappedRecipient, pendingChangeTo }
156
- // PendingDrop { id, dropKey, claimAddress, token, amount, message, envelopeId, depositedAt, sender }
156
+ // PendingDrop { id, dropKey, claimAddress, token, amount, message, envelopeId, depositedAt, rejected, sender }
157
157
 
158
- // 선택한 pending 드롭을 인박스에서 숨기고, 숨긴 목록을 다시 조회
158
+ // 선택한 pending 드롭을 거절하면 items에는 rejected=true로 남고 count/totalAmount에서는 제외된다.
159
159
  const hiddenCount = await safeDrop.rejectDrops(inbox.items.slice(0, 2).map((drop) => drop.id));
160
- const hidden = await safeDrop.listRejectedDrops(); // { items, count }
161
160
 
162
161
  // 카드 디자인 · 리더보드 (공개 — JWT 불필요)
163
162
  const envelopes = await safeDrop.listEnvelopes({ locale: 'ko' });
164
163
  const top = await safeDrop.getLeaderboard({ token: '0x…ERC20', page: 1, pageSize: 10 });
165
164
 
166
165
  // 내 drop 히스토리
167
- const page = await safeDrop.listHistories({ type: 'received', page: 1, pageSize: 20 });
166
+ const page = await safeDrop.listHistories({
167
+ type: 'received',
168
+ status: 'pending',
169
+ rejected: false,
170
+ page: 1,
171
+ pageSize: 20,
172
+ });
168
173
  ```
169
174
 
170
175
  `inbox.hasClaimedBefore === false`면 **첫 수령은 개별 claim만** 가능하다 — 일괄 수령 CTA를 이 값으로 게이트한다.
@@ -262,6 +267,7 @@ base URL은 https(또는 `http://localhost`)만 허용한다. 프로토콜 수
262
267
  | `UNAUTHORIZED` | SIWE JWT 없음·만료 → SIWE 재로그인 (`getJwt` 확인) |
263
268
  | `INVALID_OAUTH_TOKEN` | X 토큰 scope 부족(`tweet.read`+`users.read`)·app-only → 재인증 |
264
269
  | `X_CONNECTION_NOT_FOUND` | `connectX()` 먼저 (`listDrops`도 이 코드로 실패) |
270
+ | `X_ALREADY_CONNECTED` | 다른 지갑에 활성 연결됨 → 기존 지갑에서 `disconnectX()` 후 재연결 |
265
271
  | `DROP_NOT_FOUND` | 숨김 처리할 드롭이 없거나 현재 X 연결 소유가 아님 |
266
272
  | `WALLET_NOT_FOUND` | 해당 (sender, handle)의 pending 지갑 없음 — 이미 수령/환불 |
267
273
  | `PENDING_LIMIT_EXCEEDED` | pending 드롭 상한 초과 → 수령/만료 대기 안내 |
@@ -303,7 +309,7 @@ base URL은 https(또는 `http://localhost`)만 허용한다. 프로토콜 수
303
309
  | `baseUrl` | `string` | 환경변수(`getOnePopApiBaseUrl`) | one-pop-api base URL |
304
310
  | `getJwt` | `() => string \| undefined \| Promise<…>` | — | **SIWE JWT.** deposit·`listDrops`·`listHistories`·`x-connections`·batch 서명에 필요. 미제공 시 요청 전에 `UNAUTHORIZED` |
305
311
  | `fetchImpl` | `typeof fetch` | `globalThis.fetch` | 테스트/SSR 주입 |
306
- | `paths` | `Partial<PopApiPaths>` | `DEFAULT_POP_API_PATHS` (`/wallets`, `/wallets/private-key`, `/drops`, `/drops/reject`, `/drops/rejected`, `/envelopes`, `/leaderboards`, `/histories`, `/x-connections`, `/batch-claim-signature`, `/events/subscribe`) | 엔드포인트 경로 override |
312
+ | `paths` | `Partial<PopApiPaths>` | `DEFAULT_POP_API_PATHS` (`/wallets`, `/wallets/private-key`, `/drops`, `/drops/reject`, `/envelopes`, `/leaderboards`, `/histories`, `/x-connections`, `/batch-claim-signature`, `/events/subscribe`) | 엔드포인트 경로 override |
307
313
 
308
314
  ### `ViemSafeDropChainAdapter.transactionFees` 기본값
309
315
 
@@ -1,4 +1,4 @@
1
- import { C as CryptoPort, g as Secret, F as SecretHash, H as Hex, A as Address, d as ClaimSignerPort, S as SafeDropChainPort, r as OnePopDrop, I as Id, k as DropState, a as SafeDropApiPort, G as SocialIdentifier, O as OAuthProof, i as DropInbox, u as RejectedDrops, E as Envelope, p as LeaderboardPage, q as MyLeaderboardEntry, o as HistoryType, m as HistoryPage, X as XConnection, s as RecipientChangeSignature, t as RecipientSignature, h as BatchClaimSignature, v as SafeDrop } from '../createSafeDrop-ClAk8kWV.js';
1
+ import { C as CryptoPort, g as Secret, G as SecretHash, H as Hex, A as Address, d as ClaimSignerPort, S as SafeDropChainPort, t as OnePopDrop, I as Id, k as DropState, a as SafeDropApiPort, J as SocialIdentifier, O as OAuthProof, i as DropInbox, E as Envelope, r as LeaderboardPage, s as MyLeaderboardEntry, q as HistoryType, p as HistoryStatus, m as HistoryPage, X as XConnection, u as RecipientChangeSignature, v as RecipientSignature, h as BatchClaimSignature, w as SafeDrop } from '../createSafeDrop-DtWLupoE.js';
2
2
  import { PublicClient, WalletClient, Chain, Transport, Abi } from 'viem';
3
3
  import { X as XAuthPort, a as XTokenResult } from '../XAuthPort-BNJePosj.js';
4
4
 
@@ -102,6 +102,7 @@ declare class ViemSafeDropChainAdapter implements SafeDropChainPort {
102
102
  onSubmitted?: (txHash: Hex) => void | Promise<void>;
103
103
  }): Promise<{
104
104
  txHash: Hex;
105
+ dropKey: Hex;
105
106
  }>;
106
107
  /**
107
108
  * permit 서명 도메인. EIP-5267 eip712Domain()이 있으면 그 값을 쓰고, 없으면
@@ -186,6 +187,7 @@ declare class ViemSafeDropChainAdapter implements SafeDropChainPort {
186
187
  private transactionOverrides;
187
188
  private batchTransactionOverrides;
188
189
  private sponsorWrite;
190
+ private depositedDropKey;
189
191
  private confirm;
190
192
  private recoverRevertName;
191
193
  private requireAccount;
@@ -231,8 +233,6 @@ interface PopApiPaths {
231
233
  drops: string;
232
234
  /** POST — pending 드롭 숨김 (Bearer JWT + 활성 X 연결). */
233
235
  rejectDrops: string;
234
- /** GET — 숨긴 pending 드롭 목록 (Bearer JWT + 활성 X 연결). */
235
- rejectedDrops: string;
236
236
  /** GET — 카드 디자인 목록 (공개). */
237
237
  envelopes: string;
238
238
  /** GET — 토큰별 pending 잔액 상위 (공개). */
@@ -266,7 +266,6 @@ declare function getCrossAuthBaseUrl(): string;
266
266
  * POST /wallets/private-key (oauth_token 본문) → {address,private_key}
267
267
  * GET /drops (Bearer JWT) → 수령 인박스
268
268
  * POST /drops/reject (Bearer JWT) → 인박스에서 숨김
269
- * GET /drops/rejected (Bearer JWT) → 숨긴 pending 목록
270
269
  * GET /envelopes (공개) → 카드 디자인
271
270
  * GET /leaderboards?token= (공개) → pending 상위
272
271
  * GET /histories (Bearer JWT) → 온체인 이벤트
@@ -316,13 +315,13 @@ declare class HttpSafeDropApiAdapter implements SafeDropApiPort {
316
315
  claimKey: Hex;
317
316
  claimAddress: Address;
318
317
  }>;
319
- listDrops(params?: {
320
- token?: Address;
318
+ listDrops(params: {
319
+ token: Address;
320
+ dropKey?: Hex;
321
321
  }): Promise<DropInbox>;
322
322
  rejectDrops(params: {
323
323
  dropIds: readonly number[];
324
324
  }): Promise<number>;
325
- listRejectedDrops(): Promise<RejectedDrops>;
326
325
  listEnvelopes(params?: {
327
326
  locale?: string;
328
327
  }): Promise<readonly Envelope[]>;
@@ -338,6 +337,8 @@ declare class HttpSafeDropApiAdapter implements SafeDropApiPort {
338
337
  listHistories(params: {
339
338
  type: HistoryType;
340
339
  token?: Address;
340
+ status?: HistoryStatus;
341
+ rejected?: boolean;
341
342
  page?: number;
342
343
  pageSize?: number;
343
344
  }): Promise<HistoryPage>;
@@ -440,6 +441,39 @@ declare const SAFEDROP_VALIDATOR_ABI: readonly [{
440
441
 
441
442
  /** Current ONEpop mapped/unmapped deployment ABI used by the SDK. */
442
443
  declare const ONEPOP_ABI: readonly [{
444
+ readonly type: "event";
445
+ readonly name: "Deposited";
446
+ readonly inputs: readonly [{
447
+ readonly name: "addr";
448
+ readonly type: "address";
449
+ readonly indexed: true;
450
+ }, {
451
+ readonly name: "sponsor";
452
+ readonly type: "address";
453
+ readonly indexed: true;
454
+ }, {
455
+ readonly name: "dropKey";
456
+ readonly type: "bytes32";
457
+ readonly indexed: true;
458
+ }, {
459
+ readonly name: "amount";
460
+ readonly type: "uint256";
461
+ readonly indexed: false;
462
+ }, {
463
+ readonly name: "id";
464
+ readonly type: "string";
465
+ readonly indexed: false;
466
+ }, {
467
+ readonly name: "secretHash";
468
+ readonly type: "bytes32";
469
+ readonly indexed: false;
470
+ }, {
471
+ readonly name: "token";
472
+ readonly type: "address";
473
+ readonly indexed: false;
474
+ }];
475
+ readonly anonymous: false;
476
+ }, {
443
477
  readonly type: "function";
444
478
  readonly name: "activeDropOf";
445
479
  readonly stateMutability: "view";
@@ -1 +1 @@
1
- import{a,k as Q}from"../chunk-RNPX7YGJ.js";import{bytesToHex as Ae,keccak256 as Ce,recoverAddress as Re,toBytes as _e}from"viem";var g=class{keccak256(e){return Ce(_e(e))}randomSecret(){let e=new Uint8Array(32);return ve().getRandomValues(e),Ae(e).slice(2)}recoverAddress(e){return Re({hash:e.digest,signature:e.signature})}};function ve(){let i=globalThis.crypto;if(!i||typeof i.getRandomValues!="function")throw new Error("Secure crypto RNG (globalThis.crypto.getRandomValues) is unavailable");return i}import{serializeSignature as Ie,sign as Ee}from"viem/accounts";var f=class{async signDigest(e){try{let t=await Ee({hash:e.digest,privateKey:e.claimKey});return Ie(t)}catch(t){throw new a("SIGN_FAILED","Failed to sign claim digest with temp key",{cause:t instanceof Error?t.message:String(t)})}}};import{BaseError as ce,ContractFunctionRevertedError as te,createWalletClient as ne,http as Se,keccak256 as M,parseSignature as ie,toBytes as P,toHex as re}from"viem";import{privateKeyToAccount as ae,serializeSignature as se,sign as oe}from"viem/accounts";var ee=[{name:"sponsor",type:"address"},{name:"amount",type:"uint96"},{name:"claimAddr",type:"address"},{name:"recipient",type:"address"},{name:"secretHash",type:"bytes32"},{name:"id",type:"string"}],D=[{name:"dropKeys",type:"bytes32[]"},{name:"records",type:"tuple[]",components:ee}],xe=["AlreadyMapped","AmountOverflow","ChangeAlreadyRequested","ChangeInProgress","CountExceedsPending","DropAlreadyExists","DropNotFound","ECDSAInvalidSignature","EmptyId","IdMismatch","IdNotMapped","InvalidClaimSignature","InvalidShortString","InvalidValidatorNonce","InvalidValidatorSignature","NoPendingChange","NotRecipient","NotSponsor","PendingLimitExceeded","RecipientNotEmpty","ReentrancyGuardReentrantCall","SameRecipient","SecretMismatch","ValidatorSigExpired","ZeroAmount","ZeroClaimAddress","ZeroCount","ZeroRecipient","ZeroSbt","ZeroSecretHash","ZeroToken","ZeroValidator"],N=[...xe.map(i=>({type:"error",name:i,inputs:[]})),{type:"error",name:"ECDSAInvalidSignatureLength",inputs:[{name:"length",type:"uint256"}]},{type:"error",name:"ECDSAInvalidSignatureS",inputs:[{name:"s",type:"bytes32"}]},{type:"error",name:"SafeERC20FailedOperation",inputs:[{name:"token",type:"address"}]},{type:"error",name:"StringTooLong",inputs:[{name:"str",type:"string"}]}],d=[{type:"function",name:"activeDropOf",stateMutability:"view",inputs:[{name:"sponsor",type:"address"},{name:"claimAddr",type:"address"}],outputs:[{type:"bytes32"}]},{type:"function",name:"drops",stateMutability:"view",inputs:[{name:"dropKey",type:"bytes32"}],outputs:ee},{type:"function",name:"token",stateMutability:"view",inputs:[],outputs:[{type:"address"}]},{type:"function",name:"claimDigest",stateMutability:"view",inputs:[{name:"recipient",type:"address"},{name:"id",type:"string"},{name:"dropKey",type:"bytes32"}],outputs:[{type:"bytes32"}]},{type:"function",name:"claimedRecipientOf",stateMutability:"view",inputs:[{name:"id",type:"string"}],outputs:[{type:"address"}]},{type:"function",name:"pendingDropsByXid",stateMutability:"view",inputs:[{name:"id",type:"string"}],outputs:D},{type:"function",name:"pendingDropsByRecipient",stateMutability:"view",inputs:[{name:"recipient",type:"address"}],outputs:D},{type:"function",name:"pendingDropsOf",stateMutability:"view",inputs:[{name:"sponsor",type:"address"}],outputs:D},{type:"function",name:"depositMapped",stateMutability:"nonpayable",inputs:[{name:"amount",type:"uint256"},{name:"id",type:"string"},{name:"permitDeadline",type:"uint256"},{name:"v",type:"uint8"},{name:"r",type:"bytes32"},{name:"s",type:"bytes32"}],outputs:[]},{type:"function",name:"withdrawUnmapped",stateMutability:"nonpayable",inputs:[{name:"recipient",type:"address"},{name:"id",type:"string"},{name:"dropKey",type:"bytes32"},{name:"signature",type:"bytes"},{name:"secret",type:"bytes"}],outputs:[]},{type:"function",name:"withdrawUnmappedBatchByKeys",stateMutability:"nonpayable",inputs:[{name:"recipient",type:"address"},{name:"id",type:"string"},{name:"anchorDropKey",type:"bytes32"},{name:"signature",type:"bytes"},{name:"secret",type:"bytes"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"dropKeys",type:"bytes32[]"},{name:"validatorSignature",type:"bytes"}],outputs:[]},{type:"function",name:"withdrawMapped",stateMutability:"nonpayable",inputs:[{name:"dropKey",type:"bytes32"}],outputs:[]},{type:"function",name:"batchWithdrawMapped",stateMutability:"nonpayable",inputs:[{name:"count",type:"uint256"}],outputs:[]},{type:"function",name:"batchWithdrawMapped",stateMutability:"nonpayable",inputs:[{name:"dropKeys",type:"bytes32[]"}],outputs:[]},{type:"function",name:"refund",stateMutability:"nonpayable",inputs:[{name:"dropKey",type:"bytes32"}],outputs:[]},{type:"function",name:"changeNonceById",stateMutability:"view",inputs:[{name:"idKey",type:"bytes32"}],outputs:[{type:"uint256"}]},{type:"function",name:"pendingRecipientChange",stateMutability:"view",inputs:[{name:"idKey",type:"bytes32"}],outputs:[{name:"newRecipient",type:"address"}]},{type:"function",name:"requestRecipientChange",stateMutability:"nonpayable",inputs:[{name:"id",type:"string"},{name:"newRecipient",type:"address"}],outputs:[]},{type:"function",name:"completeRecipientChange",stateMutability:"nonpayable",inputs:[{name:"id",type:"string"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"validatorSignature",type:"bytes"}],outputs:[]},{type:"function",name:"cancelRecipientChange",stateMutability:"nonpayable",inputs:[{name:"id",type:"string"}],outputs:[]},{type:"function",name:"resetRecipient",stateMutability:"nonpayable",inputs:[{name:"id",type:"string"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"validatorSignature",type:"bytes"}],outputs:[]},...N];var C=[{type:"function",name:"deposit",stateMutability:"nonpayable",inputs:[{name:"claimAddr",type:"address"},{name:"amount",type:"uint256"},{name:"id",type:"string"},{name:"secretHash",type:"bytes32"},{name:"deadline",type:"uint256"},{name:"v",type:"uint8"},{name:"r",type:"bytes32"},{name:"s",type:"bytes32"}],outputs:[]},{type:"function",name:"token",stateMutability:"view",inputs:[],outputs:[{type:"address"}]},...N],b=[{type:"function",name:"name",stateMutability:"view",inputs:[],outputs:[{type:"string"}]},{type:"function",name:"nonces",stateMutability:"view",inputs:[{name:"owner",type:"address"}],outputs:[{type:"uint256"}]},{type:"function",name:"eip712Domain",stateMutability:"view",inputs:[],outputs:[{name:"fields",type:"bytes1"},{name:"name",type:"string"},{name:"version",type:"string"},{name:"chainId",type:"uint256"},{name:"verifyingContract",type:"address"},{name:"salt",type:"bytes32"},{name:"extensions",type:"uint256[]"}]}],k={Permit:[{name:"owner",type:"address"},{name:"spender",type:"address"},{name:"value",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"}]};var w=[{type:"function",name:"validator",stateMutability:"view",inputs:[],outputs:[{type:"address"}]},{type:"function",name:"validatorClaimDigest",stateMutability:"view",inputs:[{name:"recipient",type:"address"},{name:"id",type:"string"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"}],outputs:[{type:"bytes32"}]},{type:"function",name:"validatorNonceById",stateMutability:"view",inputs:[{name:"idHash",type:"bytes32"}],outputs:[{type:"uint256"}]},{type:"function",name:"claimedRecipientOf",stateMutability:"view",inputs:[{name:"id",type:"string"}],outputs:[{type:"address"}]},{type:"error",name:"ValidatorSigExpired",inputs:[]},{type:"error",name:"InvalidValidatorNonce",inputs:[]}];var Oe="0x0000000000000000000000000000000000000000",De=`0x${"00".repeat(32)}`,Ne={gas:BigInt(1e6),batchBaseGas:BigInt(1e6),batchGasPerDrop:BigInt(75e4),maxBatchGas:BigInt(3e7),maxFeePerGas:BigInt(4e9),maxPriorityFeePerGas:BigInt(1e9)},de=BigInt(1800),T=class{constructor(e){if(this.address=e.address,this.publicClient=e.publicClient,this.walletClient=e.walletClient,this.chain=e.chain,this.transport=e.transport??Se(),this.transactionFees={...Ne,...e.withdrawFees,...e.transactionFees},this.transactionFees.gas<=BigInt(0)||this.transactionFees.batchBaseGas<=BigInt(0)||this.transactionFees.batchGasPerDrop<=BigInt(0)||this.transactionFees.maxBatchGas<=BigInt(0)||this.transactionFees.maxFeePerGas<=BigInt(0)||this.transactionFees.maxPriorityFeePerGas<=BigInt(0)||this.transactionFees.maxPriorityFeePerGas>this.transactionFees.maxFeePerGas)throw new a("INVALID_PARAM","invalid EIP-1559 gas configuration");this.depositWithPermit=t=>this.permitDeposit(t)}async getDropByKey(e){try{let[t,n,r,s,c,u]=await this.publicClient.readContract({address:this.address,abi:d,functionName:"drops",args:[e]});return t.toLowerCase()===Oe?null:{dropKey:e,sponsor:t,amount:n,claimAddress:r,recipient:s,secretHash:c,id:u}}catch(t){throw p("drops",t)}}async getDropKeyByClaimAddress(e,t){try{let n=await this.publicClient.readContract({address:this.address,abi:d,functionName:"activeDropOf",args:[t,e]});return n===De?null:n}catch(n){throw p("activeDropOf",n)}}async getPendingDropsById(e){try{let[t,n]=await this.publicClient.readContract({address:this.address,abi:d,functionName:"pendingDropsByXid",args:[e.id]});return n.map((r,s)=>H(t[s],r))}catch(t){throw p("pendingDropsByXid",t)}}async getPendingDropsByRecipient(e){try{let[t,n]=await this.publicClient.readContract({address:this.address,abi:d,functionName:"pendingDropsByRecipient",args:[e.recipient]});return n.map((r,s)=>H(t[s],r))}catch(t){throw p("pendingDropsByRecipient",t)}}async getPendingDropsBySponsor(e){try{let[t,n]=await this.publicClient.readContract({address:this.address,abi:d,functionName:"pendingDropsOf",args:[e.sponsor]});return n.map((r,s)=>H(t[s],r))}catch(t){throw p("pendingDropsOf",t)}}async getDrop(e,t){let n=await this.getDropKeyByClaimAddress(e,t);if(!n)return null;let[r,s]=await Promise.all([this.getDropByKey(n),this.escrowToken()]);return r&&s?{...r,token:s}:null}async escrowToken(){try{return await this.publicClient.readContract({address:this.address,abi:C,functionName:"token"})}catch{throw new a("CHAIN_ERROR","token() failed")}}async getClaimDigest(e){try{return await this.publicClient.readContract({address:this.address,abi:d,functionName:"claimDigest",args:[e.recipient,e.id,e.dropKey]})}catch(t){throw p("claimDigest",t)}}async permitDeposit(e){try{let t=this.requireAccount(),n=e.token,[r,s,c]=await Promise.all([this.publicClient.readContract({address:this.address,abi:C,functionName:"token"}),this.publicClient.readContract({address:n,abi:b,functionName:"nonces",args:[t.address]}),this.permitDomain(n)]);if(r.toLowerCase()!==n.toLowerCase())throw new a("INVALID_TOKEN","token does not match the escrow token",{expected:r,received:e.token});let u=BigInt(Math.floor(Date.now()/1e3))+de,l=await this.walletClient.signTypedData({account:t,domain:{...c,chainId:this.chain.id,verifyingContract:n},types:k,primaryType:"Permit",message:{owner:t.address,spender:this.address,value:e.amount,nonce:s,deadline:u}}),{r:I,s:E,v:x,yParity:S}=ie(l),m=await this.walletClient.writeContract({address:this.address,abi:C,functionName:"deposit",args:[e.claimAddress,e.amount,e.id,e.secretHash,u,Number(x??BigInt(S+27)),I,E],account:t,chain:this.chain,...this.transactionOverrides()});return await e.onSubmitted?.(m),await this.confirm("depositWithPermit",m),{txHash:m}}catch(t){throw p("depositWithPermit",t)}}async depositMapped(e){try{let t=this.requireAccount(),n=e.token,[r,s,c]=await Promise.all([this.publicClient.readContract({address:this.address,abi:d,functionName:"token"}),this.publicClient.readContract({address:n,abi:b,functionName:"nonces",args:[t.address]}),this.permitDomain(n)]);if(r.toLowerCase()!==n.toLowerCase())throw new a("INVALID_TOKEN","token does not match the escrow token",{expected:r,received:e.token});let u=BigInt(Math.floor(Date.now()/1e3))+de,l=await this.walletClient.signTypedData({account:t,domain:{...c,chainId:this.chain.id,verifyingContract:n},types:k,primaryType:"Permit",message:{owner:t.address,spender:this.address,value:e.amount,nonce:s,deadline:u}}),{r:I,s:E,v:x,yParity:S}=ie(l),m=[e.amount,e.id,u,Number(x??BigInt(S+27)),I,E];await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"depositMapped",args:m,account:t});let O=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"depositMapped",args:m,account:t,chain:this.chain,...this.transactionOverrides()});return await e.onSubmitted?.(O),await this.confirm("depositMapped",O),{txHash:O}}catch(t){throw p("depositMapped",t)}}async permitDomain(e){try{let t=await this.publicClient.readContract({address:e,abi:b,functionName:"eip712Domain"});return{name:t[1],version:t[2]}}catch{return{name:await this.publicClient.readContract({address:e,abi:b,functionName:"name"}),version:"1"}}}async withdrawUnmapped(e){try{let t=ae(e.claimKey),n=await this.publicClient.readContract({address:this.address,abi:d,functionName:"claimDigest",args:[e.recipient,e.id,e.dropKey]}),r=e.signature??se(await oe({hash:n,privateKey:e.claimKey})),c=await ne({account:t,chain:this.chain,transport:this.transport}).writeContract({address:this.address,abi:d,functionName:"withdrawUnmapped",args:[e.recipient,e.id,e.dropKey,r,re(P(e.secret))],...this.transactionOverrides()});return await e.onSubmitted?.(c),await this.confirm("withdrawUnmapped",c),c}catch(t){throw pe("withdrawUnmapped",t)}}async withdrawMapped(e){let t=this.requireAccount();try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"withdrawMapped",args:[e.dropKey],account:t});let n=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"withdrawMapped",args:[e.dropKey],account:t,chain:this.chain,...this.transactionOverrides()});return await e.onSubmitted?.(n),await this.confirm("withdrawMapped",n),n}catch(n){throw p("withdrawMapped",n)}}async batchWithdrawMapped(e){if(!Number.isSafeInteger(e.count)||e.count<=0)throw new a("INVALID_PARAM","count must be a positive safe integer");let t=this.batchTransactionOverrides(e.count),n=this.requireAccount();try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"batchWithdrawMapped",args:[BigInt(e.count)],account:n});let r=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"batchWithdrawMapped",args:[BigInt(e.count)],account:n,chain:this.chain,...t});return await this.confirm("batchWithdrawMapped",r),r}catch(r){throw p("batchWithdrawMapped",r)}}async batchWithdrawMappedByKeys(e){if(!e.dropKeys.length)throw new a("INVALID_PARAM","dropKeys must not be empty");let t=this.batchTransactionOverrides(e.dropKeys.length),n=this.requireAccount(),r=[e.dropKeys];try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"batchWithdrawMapped",args:r,account:n});let s=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"batchWithdrawMapped",args:r,account:n,chain:this.chain,...t});return await this.confirm("batchWithdrawMapped",s),s}catch(s){throw p("batchWithdrawMapped",s)}}async withdrawUnmappedBatchByKeys(e){let t=e.dropKeys.filter(r=>r.toLowerCase()!==e.anchorDropKey.toLowerCase()),n=this.batchTransactionOverrides(t.length+1);try{let r=ae(e.claimKey),s=await this.publicClient.readContract({address:this.address,abi:d,functionName:"claimDigest",args:[e.recipient,e.id,e.anchorDropKey]}),c=se(await oe({hash:s,privateKey:e.claimKey})),l=await ne({account:r,chain:this.chain,transport:this.transport}).writeContract({address:this.address,abi:d,functionName:"withdrawUnmappedBatchByKeys",args:[e.recipient,e.id,e.anchorDropKey,c,re(P(e.secret)),e.nonce,e.deadline,t,e.validatorSignature],...n});return await this.confirm("withdrawUnmappedBatchByKeys",l),l}catch(r){throw pe("withdrawUnmappedBatchByKeys",r)}}async getValidatorNonce(e){try{return await this.publicClient.readContract({address:this.address,abi:w,functionName:"validatorNonceById",args:[M(P(e.id))]})}catch(t){throw p("validatorNonceById",t)}}async getValidatorClaimDigest(e){try{return await this.publicClient.readContract({address:this.address,abi:w,functionName:"validatorClaimDigest",args:[e.recipient,e.id,e.nonce,e.deadline]})}catch(t){throw p("validatorClaimDigest",t)}}async getValidator(){try{return await this.publicClient.readContract({address:this.address,abi:w,functionName:"validator"})}catch(e){throw p("validator",e)}}async getClaimedRecipient(e){try{return await this.publicClient.readContract({address:this.address,abi:d,functionName:"claimedRecipientOf",args:[e.id]})}catch(t){throw p("claimedRecipientOf",t)}}async refundByKey(e){let t=this.requireAccount();try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"refund",args:[e.dropKey],account:t});let n=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"refund",args:[e.dropKey],account:t,chain:this.chain,...this.transactionOverrides()});return await this.confirm("refund",n),n}catch(n){throw p("refund",n)}}async getChangeNonce(e){try{return await this.publicClient.readContract({address:this.address,abi:d,functionName:"changeNonceById",args:[M(P(e.id))]})}catch(t){throw p("changeNonceById",t)}}async getPendingRecipientChange(e){try{return await this.publicClient.readContract({address:this.address,abi:d,functionName:"pendingRecipientChange",args:[M(P(e.id))]})}catch(t){throw p("pendingRecipientChange",t)}}async requestRecipientChange(e){return this.currentContractWrite("requestRecipientChange",[e.id,e.newRecipient])}async completeRecipientChange(e){return this.currentContractWrite("completeRecipientChange",[e.id,e.nonce,e.deadline,e.signature])}async cancelRecipientChange(e){return this.currentContractWrite("cancelRecipientChange",[e.id])}async resetRecipient(e){let t=this.requireAccount();try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"resetRecipient",args:[e.id,e.nonce,e.deadline,e.signature],account:t});let n=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"resetRecipient",args:[e.id,e.nonce,e.deadline,e.signature],account:t,chain:this.chain,...this.transactionOverrides()});return await this.confirm("resetRecipient",n),n}catch(n){throw p("resetRecipient",n)}}async currentContractWrite(e,t){let n=this.requireAccount();try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:e,args:t,account:n});let r=await this.walletClient.writeContract({address:this.address,abi:d,functionName:e,args:t,account:n,chain:this.chain,...this.transactionOverrides()});return await this.confirm(e,r),r}catch(r){throw p(e,r)}}transactionOverrides(e=this.transactionFees.gas){return{type:"eip1559",gas:e,maxFeePerGas:this.transactionFees.maxFeePerGas,maxPriorityFeePerGas:this.transactionFees.maxPriorityFeePerGas}}batchTransactionOverrides(e){if(!Number.isSafeInteger(e)||e<=0)throw new a("INVALID_PARAM","batch count must be a positive safe integer");let t=this.transactionFees.batchBaseGas+this.transactionFees.batchGasPerDrop*BigInt(e);if(t>this.transactionFees.maxBatchGas)throw new a("INVALID_PARAM","batch gas exceeds maxBatchGas",{count:e,gas:t.toString(),maxBatchGas:this.transactionFees.maxBatchGas.toString()});return this.transactionOverrides(t)}async sponsorWrite(e,t){try{let n=await t();return await this.confirm(e,n),n}catch(n){throw p(e,n)}}async confirm(e,t){let n=await this.publicClient.waitForTransactionReceipt({hash:t});if(n.status!=="success"){let r=await this.recoverRevertName(t,n.blockNumber),s=r?`SafeDrop.${e} reverted: ${r}`:`transaction reverted: ${t}`;throw new a("CHAIN_ERROR",s,{revertName:r,txHash:t})}}async recoverRevertName(e,t){try{let n=await this.publicClient.getTransaction({hash:e});await this.publicClient.call({account:n.from,to:n.to??void 0,data:n.input,value:n.value,blockNumber:t});return}catch(n){return B(n)}}requireAccount(){let e=this.walletClient.account;if(!e)throw new a("CHAIN_ERROR","walletClient has no account (connect a wallet first)");return e}};function H(i,e){return{dropKey:i,sponsor:e.sponsor,amount:e.amount,claimAddress:e.claimAddr,recipient:e.recipient,secretHash:e.secretHash,id:e.id}}function p(i,e){if(e instanceof a)return e;let t=B(e),n=e instanceof Error?e.message:String(e),r=t?`SafeDrop.${i} reverted: ${t}`:`SafeDrop.${i} failed`;return new a("CHAIN_ERROR",r,{cause:n,revertName:t})}function pe(i,e){if(e instanceof a)return e;let t=B(e),n=e instanceof ce?e.walk(c=>{let u=c;return typeof u.code=="number"||u.data!==void 0}):void 0,r={revertName:t};typeof n?.code=="number"&&(r.rpcCode=n.code),typeof n?.details=="string"&&(r.rpcMessage=n.details),typeof n?.data=="string"&&(r.rpcData=n.data);let s=t?`SafeDrop.${i} reverted: ${t}`:`SafeDrop.${i} failed`;return new a("CHAIN_ERROR",s,r)}function B(i){if(!(i instanceof ce))return;let e=i.walk(t=>t instanceof te);if(e instanceof te)return e.data?.errorName??e.reason??void 0}var ke=BigInt(500),Me=BigInt(1e4),U={dev:{apiBaseUrl:"https://dev-one-pop-api.onechain.nexus/api",contracts:{onePop:"0xfBadB337e634757ca8F8EEB7682acF06bA297d85",permitErc20:"0xFaDAB54449262178aE0562F5D8416bBeF4659714",nft:"0x11ce973082c7B90aB2Fc789949CC04e1F85397ff",nftMinter:"0xfBadB337e634757ca8F8EEB7682acF06bA297d85",validator:"0xF30d8e0544f0b92A6987522f4F696D3915B579b4",feeRecipient:"0xF30d8e0544f0b92A6987522f4F696D3915B579b4"}},stage:{apiBaseUrl:"https://stg-one-pop-api.onechain.nexus/api",contracts:{onePop:"0x4c4599fFa1D83bB9689d9a0C557fF2EB35443949",permitErc20:"0xFaDAB54449262178aE0562F5D8416bBeF4659714",nft:"0x0535fce7113cf48f21C32472bBA929F8F31ab05c",nftMinter:"0x4c4599fFa1D83bB9689d9a0C557fF2EB35443949",validator:"0xa953af3742345dFC2BdcA30cBa79D8313b0a3B61",feeRecipient:"0xa953af3742345dFC2BdcA30cBa79D8313b0a3B61"}},production:{apiBaseUrl:"https://one-pop-api.onechain.nexus/api"}},V={createWallet:"/wallets",dropMetadata:"/drops/metadata",retrievePrivateKey:"/wallets/private-key",drops:"/drops",rejectDrops:"/drops/reject",rejectedDrops:"/drops/rejected",envelopes:"/envelopes",leaderboards:"/leaderboards",leaderboardMe:"/leaderboards/me",histories:"/histories",xConnections:"/x-connections",batchClaimSignature:"/batch-claim-signature",feedbacks:"/feedbacks",revealYou:"/reveal-you",recipientChangeSignature:"/recipient-change-signature",recipientResetSignature:"/recipient-reset-signature",eventsSubscribe:"/events/subscribe"},He="https://dev-cross-auth.crosstoken.io";function F(i){try{return import.meta.env?.[i]}catch{return}}function R(i){if(!(typeof process>"u"||!process.env))switch(i){case"NEXT_PUBLIC_ONE_POP_ENVIRONMENT":return process.env.NEXT_PUBLIC_ONE_POP_ENVIRONMENT;case"ONE_POP_ENVIRONMENT":return process.env.ONE_POP_ENVIRONMENT;case"NEXT_PUBLIC_ONE_POP_API_BASE_URL":return process.env.NEXT_PUBLIC_ONE_POP_API_BASE_URL;case"NEXT_PUBLIC_CROSS_AUTH_URL":return process.env.NEXT_PUBLIC_CROSS_AUTH_URL;default:return}}function K(){let i=F("VITE_ONE_POP_ENVIRONMENT")??R("NEXT_PUBLIC_ONE_POP_ENVIRONMENT")??R("ONE_POP_ENVIRONMENT");return Be(i)}function Be(i){switch(i?.toLowerCase()){case"dev":case"development":return"dev";case"stg":case"stage":case"staging":return"stage";case void 0:case"production":case"prod":return"production";default:throw new Error(`[pop] Invalid environment: ${i}`)}}function ue(){return U[K()]}function L(){return Ue(K())}function Ue(i){let e=U[i].contracts;if(!e)throw new Error(`[pop] Contract addresses are not configured for ${i}`);return e}function q(){let e=F("VITE_ONE_POP_API_BASE_URL")??R("NEXT_PUBLIC_ONE_POP_API_BASE_URL")??ue().apiBaseUrl;return ye(e),e}function $(){let e=(F("VITE_CROSS_AUTH_URL")??R("NEXT_PUBLIC_CROSS_AUTH_URL")??He).replace(/\/+$/,"");return ye(e),e}function ye(i){let e;try{e=new URL(i)}catch{throw new Error(`[pop] Invalid base URL: ${i}`)}if(e.protocol==="https:")return;let t=e.hostname==="localhost"||e.hostname==="127.0.0.1"||e.hostname.endsWith(".local");if(!(e.protocol==="http:"&&t))throw new Error(`[pop] base URL must be https (or http://localhost for dev). Got: ${i}`)}var Ve={INVALID_PARAM:"INVALID_PARAM",RATE_LIMITED:"RATE_LIMITED",INVALID_OAUTH_TOKEN:"INVALID_OAUTH_TOKEN",UNAUTHORIZED:"UNAUTHORIZED",WALLET_NOT_FOUND:"WALLET_NOT_FOUND",SEND_BLOCKED:"SEND_BLOCKED",ENVELOPE_NOT_FOUND:"ENVELOPE_NOT_FOUND",PENDING_LIMIT_EXCEEDED:"PENDING_LIMIT_EXCEEDED",DROP_NOT_FOUND:"DROP_NOT_FOUND",IDENTIFIER_NOT_MAPPED:"IDENTIFIER_NOT_MAPPED",X_CONNECTION_NOT_FOUND:"X_CONNECTION_NOT_FOUND"},_=140,A=class{constructor(e={}){this.baseUrl=(e.baseUrl??q()).replace(/\/+$/,"");let t=e.fetchImpl??globalThis.fetch;if(!t)throw new Error("fetch is unavailable; provide options.fetchImpl");this.fetchImpl=t,this.getJwt=e.getJwt,this.paths={...V,...e.paths}}async createClaimWallet(e){let t=await this.request(this.paths.createWallet,{method:"POST",auth:!0,payload:{identifier:e.recipient.handle,oauth_type:e.recipient.provider,sender_address:e.sender}});if(!t?.address)throw new a("API_ERROR","createClaimWallet: missing address in response",{body:t});if(!t.identifier)throw new a("API_ERROR","createClaimWallet: missing identifier in response",{body:t});return{claimAddress:t.address,id:t.identifier,isMapped:t.is_mapped===!0}}async recordDropMetadata(e){if(e.message&&[...e.message].length>_)throw new a("INVALID_PARAM",`message must be <= ${_} runes`);await this.request(this.paths.dropMetadata,{method:"POST",auth:!0,query:{tx_hash:e.txHash},payload:{...e.message?{message:e.message}:{},...e.envelopeId?{envelope_id:e.envelopeId}:{}}})}async retrieveClaimKey(e){let t=await this.request(this.paths.retrievePrivateKey,{method:"POST",payload:{oauth_token:e.oauth.accessToken,oauth_type:e.oauth.provider,sender_address:e.senderAddress,address:e.claimAddress}});if(t?.private_key&&t.address){if(t.address.toLowerCase()!==e.claimAddress.toLowerCase())throw new a("API_ERROR","retrieveClaimKey: returned a different address");return{isMapped:!1,claimKey:t.private_key,claimAddress:t.address}}if(t?.is_mapped===!0)return{isMapped:!0};throw new a("API_ERROR","retrieveClaimKey: missing key/address in response",{body:t})}async listDrops(e={}){let t=await this.request(this.paths.drops,{method:"GET",auth:!0,query:{token:e.token}});return{items:(t?.items??[]).map(le),count:t?.count??0,totalAmount:y(t?.total_amount,"drops.total_amount"),hasClaimedBefore:t?.has_claimed_before===!0,mappedRecipient:h(t?.mapped_recipient),pendingChangeTo:h(t?.pending_change_to)}}async rejectDrops(e){if(!Array.isArray(e.dropIds)||e.dropIds.length===0||e.dropIds.length>100||e.dropIds.some(n=>!Number.isSafeInteger(n)||n<=0))throw new a("INVALID_PARAM","dropIds must contain 1-100 positive integers");return(await this.request(this.paths.rejectDrops,{method:"POST",auth:!0,payload:{drop_ids:e.dropIds}}))?.count??0}async listRejectedDrops(){let e=await this.request(this.paths.rejectedDrops,{method:"GET",auth:!0});return{items:(e?.items??[]).map(le),count:e?.count??0}}async listEnvelopes(e={}){return((await this.request(this.paths.envelopes,{method:"GET",query:{locale:e.locale}}))?.items??[]).map(n=>({id:o(n.id),name:o(n.name),imageUrl:o(n.image_url),badge:o(n.badge),sortOrder:Number(n.sort_order??0)}))}async getLeaderboard(e){if(!e.token)throw new a("INVALID_PARAM","getLeaderboard requires a token address");let t=await this.request(this.paths.leaderboards,{method:"GET",query:{token:e.token,page:e.page,page_size:e.pageSize,identifier:e.identifier}});return{items:(t?.items??[]).map(he),page:t?.page??1,pageSize:t?.page_size??0,total:t?.total??0}}async getMyLeaderboardEntry(e){let t=await this.request(this.paths.leaderboardMe,{method:"GET",auth:!0,query:{token:e.token}});return{...he(t??{}),rank:we(t?.rank)}}async listHistories(e){if(!e?.type)throw new a("INVALID_PARAM","listHistories requires type");let t=await this.request(this.paths.histories,{method:"GET",auth:!0,query:{type:e.type,token:e.token,page:e.page,page_size:e.pageSize}});return{items:(t?.items??[]).map(n=>({id:Number(n.id??0),type:o(n.type),status:o(n.status),token:o(n.token),amount:y(n.amount,"history.amount"),claimAddress:o(n.claim_address),depositTxHash:o(n.deposit_tx_hash),depositedAt:o(n.deposited_at),resolvedTxHash:h(n.resolved_tx_hash),resolvedAt:h(n.resolved_at),message:o(n.message),feedback:h(n.feedback),envelopeId:o(n.envelope_id),sender:ge(n.sender),receiver:ge(n.receiver)})),page:t?.page??1,pageSize:t?.page_size??0,total:t?.total??0}}async getXConnection(){let e=await this.request(this.paths.xConnections,{method:"GET",auth:!0,notFoundAsNull:!0});return e?me(e):null}async connectX(e){let t=await this.request(this.paths.xConnections,{method:"POST",auth:!0,payload:{oauth_token:e.oauth.accessToken}});return me(t??{})}async disconnectX(){await this.request(this.paths.xConnections,{method:"DELETE",auth:!0,notFoundAsNull:!0})}async submitFeedback(e){if(!Number.isSafeInteger(e.dropId)||e.dropId<=0)throw new a("INVALID_PARAM","dropId must be a positive integer");if(!e.message.trim()||[...e.message.trim()].length>_)throw new a("INVALID_PARAM",`message must be 1-${_} runes`);let t=await this.request(this.paths.feedbacks,{method:"PUT",auth:!0,query:{drop_id:e.dropId},payload:{message:e.message}});return o(t?.message)}async setRevealYou(e){return(await this.request(this.paths.revealYou,{method:"PUT",auth:!0,payload:{reveal_you:e.revealYou}}))?.reveal_you===!0}async requestRecipientChangeSignature(e){let t=await this.request(this.paths.recipientChangeSignature,{method:"POST",auth:!0,payload:fe(e)});return{...be(t,e),newRecipient:o(t?.new_recipient)}}async requestRecipientResetSignature(e){let t=await this.request(this.paths.recipientResetSignature,{method:"POST",payload:fe(e)});return be(t,e)}async requestBatchClaimSignature(e){let t=await this.request(this.paths.batchClaimSignature,{method:"POST",auth:!0,payload:{id:e.id,oauth_token:e.oauth.accessToken,nonce:e.nonce.toString(),deadline:e.deadline.toString()}}),n=o(t?.signature);if(!n)throw new a("API_ERROR","requestBatchClaimSignature: missing signature",{body:t});return{id:o(t?.id)||e.id,recipient:o(t?.recipient),nonce:v(t?.nonce)?y(t?.nonce,"batchClaim.nonce"):e.nonce,deadline:v(t?.deadline)?y(t?.deadline,"batchClaim.deadline"):e.deadline,signature:n}}async request(e,t){let n={};if(t.payload&&(n["Content-Type"]="application/json"),t.auth){let s=await this.getJwt?.();if(!s)throw new a("UNAUTHORIZED",`${e} requires a SIWE JWT (options.getJwt)`);n.Authorization=`Bearer ${s}`}let r;try{r=await this.fetchImpl(`${this.baseUrl}${e}${Fe(t.query)}`,{method:t.method,headers:n,body:t.payload?JSON.stringify(t.payload):void 0})}catch(s){throw new a("API_ERROR",`Network error calling ${e}`,{cause:s instanceof Error?s.message:String(s)})}if(r.status===404&&t.notFoundAsNull)return null;if(!r.ok){let s=await r.json().catch(()=>{}),c=s?.code_name;throw new a((c?Ve[c]:void 0)??"API_ERROR",s?.message?`${e}: ${s.message}`:`${e} responded ${r.status}`,{status:r.status,code:s?.code,codeName:c})}return r.status===204?null:await r.json().catch(()=>null)}};function Fe(i){if(!i)return"";let e=new URLSearchParams;for(let[n,r]of Object.entries(i))r!==void 0&&r!==""&&e.set(n,String(r));let t=e.toString();return t?`?${t}`:""}function v(i){return i!=null&&i!==""}function o(i){return typeof i=="string"?i:""}function h(i){return typeof i=="string"&&i?i:null}function y(i,e){if(typeof i=="bigint")return i;if(typeof i=="number"){if(!Number.isSafeInteger(i))throw new a("API_ERROR",`${e} exceeds safe-integer precision as a JSON number`,{value:i});return BigInt(i)}let t=typeof i=="string"?i.trim():"";if(!t)return BigInt(0);try{return BigInt(t)}catch{throw new a("API_ERROR",`${e} is not a valid decimal string`,{value:i})}}function le(i){let e=i??{},t=e.sender??{};return{id:Number(e.id??0),dropKey:o(e.drop_key),claimAddress:o(e.claim_address),token:o(e.token),amount:y(e.amount,"drop.amount"),message:o(e.message),envelopeId:o(e.envelope_id),depositedAt:o(e.deposited_at),sender:{address:o(t.address),handle:o(t.handle),displayName:o(t.display_name),profileImageUrl:o(t.profile_image_url)}}}function me(i){return{xUserId:o(i.x_user_id),handle:o(i.handle),displayName:o(i.display_name),profileImageUrl:o(i.profile_image_url),walletAddress:o(i.wallet_address),revealYou:i.reveal_you===!0,onchainMapped:i.onchain_mapped===!0,mappedRecipient:h(i.mapped_recipient)}}function he(i){return{identifier:o(i.identifier),balance:y(i.balance,"leaderboard.balance"),lastDepositAmount:y(i.last_deposit_amount,"leaderboard.last_deposit_amount"),rank:Number(i.rank??0),previousRank:we(i.previous_rank),profileImageUrl:o(i.profile_image_url)}}function we(i){return typeof i=="number"?i:null}function ge(i){let e=i??{};return{address:o(e.address),handle:o(e.handle),displayName:o(e.display_name),profileImageUrl:o(e.profile_image_url)}}function fe(i){return{id:i.id,oauth_token:i.oauth.accessToken,nonce:i.nonce.toString(),deadline:i.deadline.toString()}}function be(i,e){let t=o(i?.signature);if(!t)throw new a("API_ERROR","signature response is missing signature");return{id:o(i?.id)||e.id,nonce:v(i?.nonce)?y(i?.nonce,"signature.nonce"):e.nonce,deadline:v(i?.deadline)?y(i?.deadline,"signature.deadline"):e.deadline,signature:t}}var Pe=[{type:"constructor",inputs:[{name:"token_",type:"address",internalType:"contract IERC20"},{name:"validator_",type:"address",internalType:"address"},{name:"sbt_",type:"address",internalType:"contract ISoulboundToken"}],stateMutability:"nonpayable"},{type:"function",name:"MAX_PENDING_PER_SPONSOR_ID",inputs:[],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"activeDropOf",inputs:[{name:"sponsor",type:"address",internalType:"address"},{name:"claimAddr",type:"address",internalType:"address"}],outputs:[{name:"",type:"bytes32",internalType:"bytes32"}],stateMutability:"view"},{type:"function",name:"batchWithdrawMapped",inputs:[{name:"dropKeys",type:"bytes32[]",internalType:"bytes32[]"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"batchWithdrawMapped",inputs:[{name:"count",type:"uint256",internalType:"uint256"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"cancelRecipientChange",inputs:[{name:"id",type:"string",internalType:"string"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"changeNonceById",inputs:[{name:"idKey",type:"bytes32",internalType:"bytes32"}],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"changeRecipientDigest",inputs:[{name:"id",type:"string",internalType:"string"},{name:"newRecipient",type:"address",internalType:"address"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"}],outputs:[{name:"",type:"bytes32",internalType:"bytes32"}],stateMutability:"view"},{type:"function",name:"claimDigest",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"},{name:"dropKey",type:"bytes32",internalType:"bytes32"}],outputs:[{name:"",type:"bytes32",internalType:"bytes32"}],stateMutability:"view"},{type:"function",name:"claimedRecipientOf",inputs:[{name:"id",type:"string",internalType:"string"}],outputs:[{name:"",type:"address",internalType:"address"}],stateMutability:"view"},{type:"function",name:"completeRecipientChange",inputs:[{name:"id",type:"string",internalType:"string"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"},{name:"validatorSignature",type:"bytes",internalType:"bytes"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"deposit",inputs:[{name:"claimAddr",type:"address",internalType:"address"},{name:"amount",type:"uint256",internalType:"uint256"},{name:"id",type:"string",internalType:"string"},{name:"secretHash",type:"bytes32",internalType:"bytes32"},{name:"permitDeadline",type:"uint256",internalType:"uint256"},{name:"v",type:"uint8",internalType:"uint8"},{name:"r",type:"bytes32",internalType:"bytes32"},{name:"s",type:"bytes32",internalType:"bytes32"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"depositMapped",inputs:[{name:"amount",type:"uint256",internalType:"uint256"},{name:"id",type:"string",internalType:"string"},{name:"permitDeadline",type:"uint256",internalType:"uint256"},{name:"v",type:"uint8",internalType:"uint8"},{name:"r",type:"bytes32",internalType:"bytes32"},{name:"s",type:"bytes32",internalType:"bytes32"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"drops",inputs:[{name:"dropKey",type:"bytes32",internalType:"bytes32"}],outputs:[{name:"sponsor",type:"address",internalType:"address"},{name:"amount",type:"uint96",internalType:"uint96"},{name:"claimAddr",type:"address",internalType:"address"},{name:"recipient",type:"address",internalType:"address"},{name:"secretHash",type:"bytes32",internalType:"bytes32"},{name:"id",type:"string",internalType:"string"}],stateMutability:"view"},{type:"function",name:"eip712Domain",inputs:[],outputs:[{name:"fields",type:"bytes1",internalType:"bytes1"},{name:"name",type:"string",internalType:"string"},{name:"version",type:"string",internalType:"string"},{name:"chainId",type:"uint256",internalType:"uint256"},{name:"verifyingContract",type:"address",internalType:"address"},{name:"salt",type:"bytes32",internalType:"bytes32"},{name:"extensions",type:"uint256[]",internalType:"uint256[]"}],stateMutability:"view"},{type:"function",name:"pendingCountOf",inputs:[{name:"sponsor",type:"address",internalType:"address"}],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"pendingCountOf",inputs:[{name:"sponsor",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"}],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"pendingDropsByRecipient",inputs:[{name:"recipient",type:"address",internalType:"address"}],outputs:[{name:"dropKeys",type:"bytes32[]",internalType:"bytes32[]"},{name:"records",type:"tuple[]",internalType:"struct ONEpop.Drop[]",components:[{name:"sponsor",type:"address",internalType:"address"},{name:"amount",type:"uint96",internalType:"uint96"},{name:"claimAddr",type:"address",internalType:"address"},{name:"recipient",type:"address",internalType:"address"},{name:"secretHash",type:"bytes32",internalType:"bytes32"},{name:"id",type:"string",internalType:"string"}]}],stateMutability:"view"},{type:"function",name:"pendingDropsByXid",inputs:[{name:"id",type:"string",internalType:"string"}],outputs:[{name:"dropKeys",type:"bytes32[]",internalType:"bytes32[]"},{name:"records",type:"tuple[]",internalType:"struct ONEpop.Drop[]",components:[{name:"sponsor",type:"address",internalType:"address"},{name:"amount",type:"uint96",internalType:"uint96"},{name:"claimAddr",type:"address",internalType:"address"},{name:"recipient",type:"address",internalType:"address"},{name:"secretHash",type:"bytes32",internalType:"bytes32"},{name:"id",type:"string",internalType:"string"}]}],stateMutability:"view"},{type:"function",name:"pendingDropsOf",inputs:[{name:"sponsor",type:"address",internalType:"address"}],outputs:[{name:"dropKeys",type:"bytes32[]",internalType:"bytes32[]"},{name:"records",type:"tuple[]",internalType:"struct ONEpop.Drop[]",components:[{name:"sponsor",type:"address",internalType:"address"},{name:"amount",type:"uint96",internalType:"uint96"},{name:"claimAddr",type:"address",internalType:"address"},{name:"recipient",type:"address",internalType:"address"},{name:"secretHash",type:"bytes32",internalType:"bytes32"},{name:"id",type:"string",internalType:"string"}]}],stateMutability:"view"},{type:"function",name:"pendingRecipientChange",inputs:[{name:"idKey",type:"bytes32",internalType:"bytes32"}],outputs:[{name:"newRecipient",type:"address",internalType:"address"}],stateMutability:"view"},{type:"function",name:"refund",inputs:[{name:"dropKey",type:"bytes32",internalType:"bytes32"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"requestRecipientChange",inputs:[{name:"id",type:"string",internalType:"string"},{name:"newRecipient",type:"address",internalType:"address"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"resetRecipient",inputs:[{name:"id",type:"string",internalType:"string"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"},{name:"validatorSignature",type:"bytes",internalType:"bytes"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"resetRecipientDigest",inputs:[{name:"id",type:"string",internalType:"string"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"}],outputs:[{name:"",type:"bytes32",internalType:"bytes32"}],stateMutability:"view"},{type:"function",name:"sbt",inputs:[],outputs:[{name:"",type:"address",internalType:"contract ISoulboundToken"}],stateMutability:"view"},{type:"function",name:"settledCountOf",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"}],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"token",inputs:[],outputs:[{name:"",type:"address",internalType:"contract IERC20"}],stateMutability:"view"},{type:"function",name:"validator",inputs:[],outputs:[{name:"",type:"address",internalType:"address"}],stateMutability:"view"},{type:"function",name:"validatorClaimDigest",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"}],outputs:[{name:"",type:"bytes32",internalType:"bytes32"}],stateMutability:"view"},{type:"function",name:"validatorNonceById",inputs:[{name:"idKey",type:"bytes32",internalType:"bytes32"}],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"withdrawMapped",inputs:[{name:"dropKey",type:"bytes32",internalType:"bytes32"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"withdrawUnmapped",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"},{name:"dropKey",type:"bytes32",internalType:"bytes32"},{name:"signature",type:"bytes",internalType:"bytes"},{name:"secret",type:"bytes",internalType:"bytes"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"withdrawUnmappedBatch",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"},{name:"anchorDropKey",type:"bytes32",internalType:"bytes32"},{name:"signature",type:"bytes",internalType:"bytes"},{name:"secret",type:"bytes",internalType:"bytes"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"},{name:"payCount",type:"uint256",internalType:"uint256"},{name:"moveCount",type:"uint256",internalType:"uint256"},{name:"validatorSignature",type:"bytes",internalType:"bytes"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"withdrawUnmappedBatchByKeys",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"},{name:"anchorDropKey",type:"bytes32",internalType:"bytes32"},{name:"signature",type:"bytes",internalType:"bytes"},{name:"secret",type:"bytes",internalType:"bytes"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"},{name:"dropKeys",type:"bytes32[]",internalType:"bytes32[]"},{name:"validatorSignature",type:"bytes",internalType:"bytes"}],outputs:[],stateMutability:"nonpayable"},{type:"event",name:"Deposited",inputs:[{name:"addr",type:"address",indexed:!0,internalType:"address"},{name:"sponsor",type:"address",indexed:!0,internalType:"address"},{name:"dropKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"amount",type:"uint256",indexed:!1,internalType:"uint256"},{name:"id",type:"string",indexed:!1,internalType:"string"},{name:"secretHash",type:"bytes32",indexed:!1,internalType:"bytes32"},{name:"token",type:"address",indexed:!1,internalType:"address"}],anonymous:!1},{type:"event",name:"EIP712DomainChanged",inputs:[],anonymous:!1},{type:"event",name:"Moved",inputs:[{name:"claimAddr",type:"address",indexed:!0,internalType:"address"},{name:"recipient",type:"address",indexed:!0,internalType:"address"},{name:"dropKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"sponsor",type:"address",indexed:!1,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"},{name:"amount",type:"uint256",indexed:!1,internalType:"uint256"}],anonymous:!1},{type:"event",name:"RecipientChangeCancelled",inputs:[{name:"idKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"from",type:"address",indexed:!0,internalType:"address"},{name:"to",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"}],anonymous:!1},{type:"event",name:"RecipientChangeRequested",inputs:[{name:"idKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"from",type:"address",indexed:!0,internalType:"address"},{name:"to",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"}],anonymous:!1},{type:"event",name:"RecipientChanged",inputs:[{name:"idKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"from",type:"address",indexed:!0,internalType:"address"},{name:"to",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"}],anonymous:!1},{type:"event",name:"RecipientMapped",inputs:[{name:"idKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"recipient",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"}],anonymous:!1},{type:"event",name:"RecipientReset",inputs:[{name:"idKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"from",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"}],anonymous:!1},{type:"event",name:"Refunded",inputs:[{name:"claimAddr",type:"address",indexed:!0,internalType:"address"},{name:"sponsor",type:"address",indexed:!0,internalType:"address"},{name:"dropKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"id",type:"string",indexed:!1,internalType:"string"},{name:"amount",type:"uint256",indexed:!1,internalType:"uint256"},{name:"token",type:"address",indexed:!1,internalType:"address"}],anonymous:!1},{type:"event",name:"Withdrawn",inputs:[{name:"claimAddr",type:"address",indexed:!0,internalType:"address"},{name:"recipient",type:"address",indexed:!0,internalType:"address"},{name:"sponsor",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"},{name:"amount",type:"uint256",indexed:!1,internalType:"uint256"},{name:"token",type:"address",indexed:!1,internalType:"address"},{name:"sbtTokenId",type:"uint256",indexed:!1,internalType:"uint256"},{name:"dropKey",type:"bytes32",indexed:!1,internalType:"bytes32"}],anonymous:!1},{type:"error",name:"AlreadyMapped",inputs:[]},{type:"error",name:"AmountOverflow",inputs:[]},{type:"error",name:"ChangeAlreadyRequested",inputs:[]},{type:"error",name:"ChangeInProgress",inputs:[]},{type:"error",name:"CountExceedsPending",inputs:[]},{type:"error",name:"DropAlreadyExists",inputs:[]},{type:"error",name:"DropNotFound",inputs:[]},{type:"error",name:"ECDSAInvalidSignature",inputs:[]},{type:"error",name:"ECDSAInvalidSignatureLength",inputs:[{name:"length",type:"uint256",internalType:"uint256"}]},{type:"error",name:"ECDSAInvalidSignatureS",inputs:[{name:"s",type:"bytes32",internalType:"bytes32"}]},{type:"error",name:"EmptyId",inputs:[]},{type:"error",name:"IdMismatch",inputs:[]},{type:"error",name:"IdNotMapped",inputs:[]},{type:"error",name:"InvalidClaimSignature",inputs:[]},{type:"error",name:"InvalidShortString",inputs:[]},{type:"error",name:"InvalidValidatorNonce",inputs:[]},{type:"error",name:"InvalidValidatorSignature",inputs:[]},{type:"error",name:"NoPendingChange",inputs:[]},{type:"error",name:"NotRecipient",inputs:[]},{type:"error",name:"NotSponsor",inputs:[]},{type:"error",name:"PendingLimitExceeded",inputs:[]},{type:"error",name:"RecipientNotEmpty",inputs:[]},{type:"error",name:"ReentrancyGuardReentrantCall",inputs:[]},{type:"error",name:"SafeERC20FailedOperation",inputs:[{name:"token",type:"address",internalType:"address"}]},{type:"error",name:"SameRecipient",inputs:[]},{type:"error",name:"SecretMismatch",inputs:[]},{type:"error",name:"StringTooLong",inputs:[{name:"str",type:"string",internalType:"string"}]},{type:"error",name:"ValidatorSigExpired",inputs:[]},{type:"error",name:"ZeroAmount",inputs:[]},{type:"error",name:"ZeroClaimAddress",inputs:[]},{type:"error",name:"ZeroCount",inputs:[]},{type:"error",name:"ZeroRecipient",inputs:[]},{type:"error",name:"ZeroSbt",inputs:[]},{type:"error",name:"ZeroSecretHash",inputs:[]},{type:"error",name:"ZeroToken",inputs:[]},{type:"error",name:"ZeroValidator",inputs:[]}];var Le=Pe;var X=class{constructor(e={}){this.baseUrl=(e.baseUrl??$()).replace(/\/+$/,""),this.domain=e.domain??globalThis.location?.origin??"";let t=e.fetchImpl??globalThis.fetch;if(!t)throw new Error("fetch is unavailable; provide options.fetchImpl");this.fetchImpl=t}unsignedHash(e,t){return this.post("/login/unsigned-hash",{chain_id:e,address:t,domain:this.domain})}siweToken(e,t){return this.post("/login/token",{address:e,signature:t,domain:this.domain})}async post(e,t){let n;try{n=await this.fetchImpl(`${this.baseUrl}/cross-auth${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}catch(s){throw new a("API_ERROR",`cross-auth network error calling ${e}`,{cause:s instanceof Error?s.message:String(s)})}let r=await n.json().catch(()=>({}));if(!n.ok||r.data==null)throw new a("API_ERROR",`cross-auth ${e} failed`,{code:r.code,message:r.message});return r.data}};function qe(i){let e=i.apiPort??new A(i.api),t=new T({address:i.contractAddress??L().onePop,publicClient:i.publicClient,walletClient:i.walletClient,chain:i.chain,transport:i.transport,withdrawFees:i.withdrawFees,transactionFees:i.transactionFees});return Q({claimBaseUrl:i.claimBaseUrl},{api:e,chain:t,signer:new f,crypto:new g})}async function W(){let i=G(Te(32)),e=await $e().digest("SHA-256",Xe(i)),t=G(new Uint8Array(e));return{verifier:i,challenge:t,method:"S256"}}function j(){return G(Te(16))}function Te(i){let e=globalThis.crypto;if(!e?.getRandomValues)throw new Error("crypto.getRandomValues unavailable");let t=new Uint8Array(i);return e.getRandomValues(t),t}function $e(){let i=globalThis.crypto?.subtle;if(!i)throw new Error("crypto.subtle unavailable (needs https/secure context)");return i}function Xe(i){return new TextEncoder().encode(i)}function G(i){let e="";for(let n of i)e+=String.fromCharCode(n);let t=globalThis.btoa?.(e);if(t===void 0)throw new Error("btoa unavailable");return t.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var z=class{constructor(e={}){this.baseUrl=(e.baseUrl??"").replace(/\/+$/,""),this.tokenPath=e.tokenPath??"/api/x/token",this.mePath=e.mePath??"/api/x/me";let t=e.fetchImpl??globalThis.fetch;if(!t)throw new Error("fetch is unavailable; provide options.fetchImpl");this.fetchImpl=t}async exchangeCode(e){let n=await(await this.call(this.tokenPath,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({clientId:e.clientId,redirectUri:e.redirectUri,code:e.code,verifier:e.codeVerifier})})).json().catch(()=>({}));if(!n.access_token)throw new a("API_ERROR","X token exchange: missing access_token",{body:n});return{accessToken:n.access_token,scope:n.scope,expiresIn:n.expires_in,refreshToken:n.refresh_token}}async getHandle(e){let n=await(await this.call(this.mePath,{method:"GET",headers:{Authorization:`Bearer ${e}`}})).json().catch(()=>({})),r=n.data?.username??n.username;if(!r)throw new a("API_ERROR","X /me: missing username",{body:n});return{handle:r}}async call(e,t){let n;try{n=await this.fetchImpl(`${this.baseUrl}${e}`,t)}catch(r){throw new a("API_ERROR",`Network error calling ${e}`,{cause:r instanceof Error?r.message:String(r)})}if(!n.ok)throw new a("API_ERROR",`${e} responded ${n.status}`,{status:n.status});return n}};var Z="pop.xauth.verifier",Y="pop.xauth.state",Ge="https://x.com/i/oauth2/authorize",We="tweet.read users.read offline.access",J=class{constructor(e){this.opts={clientId:e.clientId,redirectUri:e.redirectUri,scope:e.scope??We,authorizeUrl:e.authorizeUrl??Ge,port:e.port,storage:e.storage??je()}}async start(){let e=await W(),t=j();this.opts.storage.set(Z,e.verifier),this.opts.storage.set(Y,t);let n=new URLSearchParams({response_type:"code",client_id:this.opts.clientId,redirect_uri:this.opts.redirectUri,scope:this.opts.scope,state:t,code_challenge:e.challenge,code_challenge_method:"S256"});return{authorizeUrl:`${this.opts.authorizeUrl}?${n.toString()}`,state:t}}async complete(e){let t=new URL(e),n=t.searchParams.get("code"),r=t.searchParams.get("state");if(!n)throw new a("API_ERROR","X callback: missing authorization code",{error:t.searchParams.get("error")});let s=this.opts.storage.get(Y);if(!r||!s||r!==s)throw new a("API_ERROR","X callback: state mismatch (possible CSRF)");let c=this.opts.storage.get(Z);if(!c)throw new a("API_ERROR","X callback: missing PKCE verifier (expired session?)");let u=await this.opts.port.exchangeCode({clientId:this.opts.clientId,redirectUri:this.opts.redirectUri,code:n,codeVerifier:c}),{handle:l}=await this.opts.port.getHandle(u.accessToken);return this.opts.storage.remove(Z),this.opts.storage.remove(Y),{oauth:{provider:"x",accessToken:u.accessToken},handle:l}}};function je(){let i=globalThis.sessionStorage;if(!i)throw new Error("sessionStorage unavailable; provide options.storage");return{get:e=>i.getItem(e),set:(e,t)=>i.setItem(e,t),remove:e=>i.removeItem(e)}}export{X as CrossAuthClient,V as DEFAULT_POP_API_PATHS,A as HttpSafeDropApiAdapter,z as HttpXAuthAdapter,d as ONEPOP_ABI,Me as ONE_POP_BPS_DENOMINATOR,U as ONE_POP_DEPLOYMENTS,ke as ONE_POP_FEE_BPS,Le as SAFEDROP_ABI,w as SAFEDROP_VALIDATOR_ABI,f as ViemClaimSignerAdapter,g as ViemCryptoAdapter,T as ViemSafeDropChainAdapter,J as XAuthClient,qe as createSafeDropClient,W as generatePkce,j as generateState,$ as getCrossAuthBaseUrl,q as getOnePopApiBaseUrl,L as getOnePopContracts,ue as getOnePopDeployment,K as getPopEnvironment};
1
+ import{a,k as Q}from"../chunk-SX7PPVTJ.js";import{bytesToHex as Ae,keccak256 as Ce,recoverAddress as Re,toBytes as _e}from"viem";var f=class{keccak256(e){return Ce(_e(e))}randomSecret(){let e=new Uint8Array(32);return ve().getRandomValues(e),Ae(e).slice(2)}recoverAddress(e){return Re({hash:e.digest,signature:e.signature})}};function ve(){let i=globalThis.crypto;if(!i||typeof i.getRandomValues!="function")throw new Error("Secure crypto RNG (globalThis.crypto.getRandomValues) is unavailable");return i}import{serializeSignature as xe,sign as Ie}from"viem/accounts";var b=class{async signDigest(e){try{let t=await Ie({hash:e.digest,privateKey:e.claimKey});return xe(t)}catch(t){throw new a("SIGN_FAILED","Failed to sign claim digest with temp key",{cause:t instanceof Error?t.message:String(t)})}}};import{BaseError as ce,ContractFunctionRevertedError as te,createWalletClient as ne,http as Se,keccak256 as H,parseEventLogs as Oe,parseSignature as ie,toBytes as T,toHex as re}from"viem";import{privateKeyToAccount as ae,serializeSignature as se,sign as oe}from"viem/accounts";var ee=[{name:"sponsor",type:"address"},{name:"amount",type:"uint96"},{name:"claimAddr",type:"address"},{name:"recipient",type:"address"},{name:"secretHash",type:"bytes32"},{name:"id",type:"string"}],D=[{name:"dropKeys",type:"bytes32[]"},{name:"records",type:"tuple[]",components:ee}],Ee=["AlreadyMapped","AmountOverflow","ChangeAlreadyRequested","ChangeInProgress","CountExceedsPending","DropAlreadyExists","DropNotFound","ECDSAInvalidSignature","EmptyId","IdMismatch","IdNotMapped","InvalidClaimSignature","InvalidShortString","InvalidValidatorNonce","InvalidValidatorSignature","NoPendingChange","NotRecipient","NotSponsor","PendingLimitExceeded","RecipientNotEmpty","ReentrancyGuardReentrantCall","SameRecipient","SecretMismatch","ValidatorSigExpired","ZeroAmount","ZeroClaimAddress","ZeroCount","ZeroRecipient","ZeroSbt","ZeroSecretHash","ZeroToken","ZeroValidator"],N=[...Ee.map(i=>({type:"error",name:i,inputs:[]})),{type:"error",name:"ECDSAInvalidSignatureLength",inputs:[{name:"length",type:"uint256"}]},{type:"error",name:"ECDSAInvalidSignatureS",inputs:[{name:"s",type:"bytes32"}]},{type:"error",name:"SafeERC20FailedOperation",inputs:[{name:"token",type:"address"}]},{type:"error",name:"StringTooLong",inputs:[{name:"str",type:"string"}]}],d=[{type:"event",name:"Deposited",inputs:[{name:"addr",type:"address",indexed:!0},{name:"sponsor",type:"address",indexed:!0},{name:"dropKey",type:"bytes32",indexed:!0},{name:"amount",type:"uint256",indexed:!1},{name:"id",type:"string",indexed:!1},{name:"secretHash",type:"bytes32",indexed:!1},{name:"token",type:"address",indexed:!1}],anonymous:!1},{type:"function",name:"activeDropOf",stateMutability:"view",inputs:[{name:"sponsor",type:"address"},{name:"claimAddr",type:"address"}],outputs:[{type:"bytes32"}]},{type:"function",name:"drops",stateMutability:"view",inputs:[{name:"dropKey",type:"bytes32"}],outputs:ee},{type:"function",name:"token",stateMutability:"view",inputs:[],outputs:[{type:"address"}]},{type:"function",name:"claimDigest",stateMutability:"view",inputs:[{name:"recipient",type:"address"},{name:"id",type:"string"},{name:"dropKey",type:"bytes32"}],outputs:[{type:"bytes32"}]},{type:"function",name:"claimedRecipientOf",stateMutability:"view",inputs:[{name:"id",type:"string"}],outputs:[{type:"address"}]},{type:"function",name:"pendingDropsByXid",stateMutability:"view",inputs:[{name:"id",type:"string"}],outputs:D},{type:"function",name:"pendingDropsByRecipient",stateMutability:"view",inputs:[{name:"recipient",type:"address"}],outputs:D},{type:"function",name:"pendingDropsOf",stateMutability:"view",inputs:[{name:"sponsor",type:"address"}],outputs:D},{type:"function",name:"depositMapped",stateMutability:"nonpayable",inputs:[{name:"amount",type:"uint256"},{name:"id",type:"string"},{name:"permitDeadline",type:"uint256"},{name:"v",type:"uint8"},{name:"r",type:"bytes32"},{name:"s",type:"bytes32"}],outputs:[]},{type:"function",name:"withdrawUnmapped",stateMutability:"nonpayable",inputs:[{name:"recipient",type:"address"},{name:"id",type:"string"},{name:"dropKey",type:"bytes32"},{name:"signature",type:"bytes"},{name:"secret",type:"bytes"}],outputs:[]},{type:"function",name:"withdrawUnmappedBatchByKeys",stateMutability:"nonpayable",inputs:[{name:"recipient",type:"address"},{name:"id",type:"string"},{name:"anchorDropKey",type:"bytes32"},{name:"signature",type:"bytes"},{name:"secret",type:"bytes"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"dropKeys",type:"bytes32[]"},{name:"validatorSignature",type:"bytes"}],outputs:[]},{type:"function",name:"withdrawMapped",stateMutability:"nonpayable",inputs:[{name:"dropKey",type:"bytes32"}],outputs:[]},{type:"function",name:"batchWithdrawMapped",stateMutability:"nonpayable",inputs:[{name:"count",type:"uint256"}],outputs:[]},{type:"function",name:"batchWithdrawMapped",stateMutability:"nonpayable",inputs:[{name:"dropKeys",type:"bytes32[]"}],outputs:[]},{type:"function",name:"refund",stateMutability:"nonpayable",inputs:[{name:"dropKey",type:"bytes32"}],outputs:[]},{type:"function",name:"changeNonceById",stateMutability:"view",inputs:[{name:"idKey",type:"bytes32"}],outputs:[{type:"uint256"}]},{type:"function",name:"pendingRecipientChange",stateMutability:"view",inputs:[{name:"idKey",type:"bytes32"}],outputs:[{name:"newRecipient",type:"address"}]},{type:"function",name:"requestRecipientChange",stateMutability:"nonpayable",inputs:[{name:"id",type:"string"},{name:"newRecipient",type:"address"}],outputs:[]},{type:"function",name:"completeRecipientChange",stateMutability:"nonpayable",inputs:[{name:"id",type:"string"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"validatorSignature",type:"bytes"}],outputs:[]},{type:"function",name:"cancelRecipientChange",stateMutability:"nonpayable",inputs:[{name:"id",type:"string"}],outputs:[]},{type:"function",name:"resetRecipient",stateMutability:"nonpayable",inputs:[{name:"id",type:"string"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"validatorSignature",type:"bytes"}],outputs:[]},...N];var R=[{type:"function",name:"deposit",stateMutability:"nonpayable",inputs:[{name:"claimAddr",type:"address"},{name:"amount",type:"uint256"},{name:"id",type:"string"},{name:"secretHash",type:"bytes32"},{name:"deadline",type:"uint256"},{name:"v",type:"uint8"},{name:"r",type:"bytes32"},{name:"s",type:"bytes32"}],outputs:[]},{type:"function",name:"token",stateMutability:"view",inputs:[],outputs:[{type:"address"}]},...N],w=[{type:"function",name:"name",stateMutability:"view",inputs:[],outputs:[{type:"string"}]},{type:"function",name:"nonces",stateMutability:"view",inputs:[{name:"owner",type:"address"}],outputs:[{type:"uint256"}]},{type:"function",name:"eip712Domain",stateMutability:"view",inputs:[],outputs:[{name:"fields",type:"bytes1"},{name:"name",type:"string"},{name:"version",type:"string"},{name:"chainId",type:"uint256"},{name:"verifyingContract",type:"address"},{name:"salt",type:"bytes32"},{name:"extensions",type:"uint256[]"}]}],k={Permit:[{name:"owner",type:"address"},{name:"spender",type:"address"},{name:"value",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"}]};var P=[{type:"function",name:"validator",stateMutability:"view",inputs:[],outputs:[{type:"address"}]},{type:"function",name:"validatorClaimDigest",stateMutability:"view",inputs:[{name:"recipient",type:"address"},{name:"id",type:"string"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"}],outputs:[{type:"bytes32"}]},{type:"function",name:"validatorNonceById",stateMutability:"view",inputs:[{name:"idHash",type:"bytes32"}],outputs:[{type:"uint256"}]},{type:"function",name:"claimedRecipientOf",stateMutability:"view",inputs:[{name:"id",type:"string"}],outputs:[{type:"address"}]},{type:"error",name:"ValidatorSigExpired",inputs:[]},{type:"error",name:"InvalidValidatorNonce",inputs:[]}];var De="0x0000000000000000000000000000000000000000",Ne=`0x${"00".repeat(32)}`,ke={gas:BigInt(1e6),batchBaseGas:BigInt(1e6),batchGasPerDrop:BigInt(75e4),maxBatchGas:BigInt(3e7),maxFeePerGas:BigInt(4e9),maxPriorityFeePerGas:BigInt(1e9)},de=BigInt(1800),A=class{constructor(e){if(this.address=e.address,this.publicClient=e.publicClient,this.walletClient=e.walletClient,this.chain=e.chain,this.transport=e.transport??Se(),this.transactionFees={...ke,...e.withdrawFees,...e.transactionFees},this.transactionFees.gas<=BigInt(0)||this.transactionFees.batchBaseGas<=BigInt(0)||this.transactionFees.batchGasPerDrop<=BigInt(0)||this.transactionFees.maxBatchGas<=BigInt(0)||this.transactionFees.maxFeePerGas<=BigInt(0)||this.transactionFees.maxPriorityFeePerGas<=BigInt(0)||this.transactionFees.maxPriorityFeePerGas>this.transactionFees.maxFeePerGas)throw new a("INVALID_PARAM","invalid EIP-1559 gas configuration");this.depositWithPermit=t=>this.permitDeposit(t)}async getDropByKey(e){try{let[t,n,r,s,p,u]=await this.publicClient.readContract({address:this.address,abi:d,functionName:"drops",args:[e]});return t.toLowerCase()===De?null:{dropKey:e,sponsor:t,amount:n,claimAddress:r,recipient:s,secretHash:p,id:u}}catch(t){throw c("drops",t)}}async getDropKeyByClaimAddress(e,t){try{let n=await this.publicClient.readContract({address:this.address,abi:d,functionName:"activeDropOf",args:[t,e]});return n===Ne?null:n}catch(n){throw c("activeDropOf",n)}}async getPendingDropsById(e){try{let[t,n]=await this.publicClient.readContract({address:this.address,abi:d,functionName:"pendingDropsByXid",args:[e.id]});return n.map((r,s)=>M(t[s],r))}catch(t){throw c("pendingDropsByXid",t)}}async getPendingDropsByRecipient(e){try{let[t,n]=await this.publicClient.readContract({address:this.address,abi:d,functionName:"pendingDropsByRecipient",args:[e.recipient]});return n.map((r,s)=>M(t[s],r))}catch(t){throw c("pendingDropsByRecipient",t)}}async getPendingDropsBySponsor(e){try{let[t,n]=await this.publicClient.readContract({address:this.address,abi:d,functionName:"pendingDropsOf",args:[e.sponsor]});return n.map((r,s)=>M(t[s],r))}catch(t){throw c("pendingDropsOf",t)}}async getDrop(e,t){let n=await this.getDropKeyByClaimAddress(e,t);if(!n)return null;let[r,s]=await Promise.all([this.getDropByKey(n),this.escrowToken()]);return r&&s?{...r,token:s}:null}async escrowToken(){try{return await this.publicClient.readContract({address:this.address,abi:R,functionName:"token"})}catch{throw new a("CHAIN_ERROR","token() failed")}}async getClaimDigest(e){try{return await this.publicClient.readContract({address:this.address,abi:d,functionName:"claimDigest",args:[e.recipient,e.id,e.dropKey]})}catch(t){throw c("claimDigest",t)}}async permitDeposit(e){try{let t=this.requireAccount(),n=e.token,[r,s,p]=await Promise.all([this.publicClient.readContract({address:this.address,abi:R,functionName:"token"}),this.publicClient.readContract({address:n,abi:w,functionName:"nonces",args:[t.address]}),this.permitDomain(n)]);if(r.toLowerCase()!==n.toLowerCase())throw new a("INVALID_TOKEN","token does not match the escrow token",{expected:r,received:e.token});let u=BigInt(Math.floor(Date.now()/1e3))+de,y=await this.walletClient.signTypedData({account:t,domain:{...p,chainId:this.chain.id,verifyingContract:n},types:k,primaryType:"Permit",message:{owner:t.address,spender:this.address,value:e.amount,nonce:s,deadline:u}}),{r:I,s:E,v:S,yParity:O}=ie(y),m=await this.walletClient.writeContract({address:this.address,abi:R,functionName:"deposit",args:[e.claimAddress,e.amount,e.id,e.secretHash,u,Number(S??BigInt(O+27)),I,E],account:t,chain:this.chain,...this.transactionOverrides()});await e.onSubmitted?.(m);let g=await this.confirm("depositWithPermit",m);return{txHash:m,dropKey:this.depositedDropKey(g.logs,t.address,e.amount,e.id,m)}}catch(t){throw c("depositWithPermit",t)}}async depositMapped(e){try{let t=this.requireAccount(),n=e.token,[r,s,p]=await Promise.all([this.publicClient.readContract({address:this.address,abi:d,functionName:"token"}),this.publicClient.readContract({address:n,abi:w,functionName:"nonces",args:[t.address]}),this.permitDomain(n)]);if(r.toLowerCase()!==n.toLowerCase())throw new a("INVALID_TOKEN","token does not match the escrow token",{expected:r,received:e.token});let u=BigInt(Math.floor(Date.now()/1e3))+de,y=await this.walletClient.signTypedData({account:t,domain:{...p,chainId:this.chain.id,verifyingContract:n},types:k,primaryType:"Permit",message:{owner:t.address,spender:this.address,value:e.amount,nonce:s,deadline:u}}),{r:I,s:E,v:S,yParity:O}=ie(y),m=[e.amount,e.id,u,Number(S??BigInt(O+27)),I,E];await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"depositMapped",args:m,account:t});let g=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"depositMapped",args:m,account:t,chain:this.chain,...this.transactionOverrides()});await e.onSubmitted?.(g);let Te=await this.confirm("depositMapped",g);return{txHash:g,dropKey:this.depositedDropKey(Te.logs,t.address,e.amount,e.id,g)}}catch(t){throw c("depositMapped",t)}}async permitDomain(e){try{let t=await this.publicClient.readContract({address:e,abi:w,functionName:"eip712Domain"});return{name:t[1],version:t[2]}}catch{return{name:await this.publicClient.readContract({address:e,abi:w,functionName:"name"}),version:"1"}}}async withdrawUnmapped(e){try{let t=ae(e.claimKey),n=await this.publicClient.readContract({address:this.address,abi:d,functionName:"claimDigest",args:[e.recipient,e.id,e.dropKey]}),r=e.signature??se(await oe({hash:n,privateKey:e.claimKey})),p=await ne({account:t,chain:this.chain,transport:this.transport}).writeContract({address:this.address,abi:d,functionName:"withdrawUnmapped",args:[e.recipient,e.id,e.dropKey,r,re(T(e.secret))],...this.transactionOverrides()});return await e.onSubmitted?.(p),await this.confirm("withdrawUnmapped",p),p}catch(t){throw pe("withdrawUnmapped",t)}}async withdrawMapped(e){let t=this.requireAccount();try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"withdrawMapped",args:[e.dropKey],account:t});let n=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"withdrawMapped",args:[e.dropKey],account:t,chain:this.chain,...this.transactionOverrides()});return await e.onSubmitted?.(n),await this.confirm("withdrawMapped",n),n}catch(n){throw c("withdrawMapped",n)}}async batchWithdrawMapped(e){if(!Number.isSafeInteger(e.count)||e.count<=0)throw new a("INVALID_PARAM","count must be a positive safe integer");let t=this.batchTransactionOverrides(e.count),n=this.requireAccount();try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"batchWithdrawMapped",args:[BigInt(e.count)],account:n});let r=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"batchWithdrawMapped",args:[BigInt(e.count)],account:n,chain:this.chain,...t});return await this.confirm("batchWithdrawMapped",r),r}catch(r){throw c("batchWithdrawMapped",r)}}async batchWithdrawMappedByKeys(e){if(!e.dropKeys.length)throw new a("INVALID_PARAM","dropKeys must not be empty");let t=this.batchTransactionOverrides(e.dropKeys.length),n=this.requireAccount(),r=[e.dropKeys];try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"batchWithdrawMapped",args:r,account:n});let s=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"batchWithdrawMapped",args:r,account:n,chain:this.chain,...t});return await this.confirm("batchWithdrawMapped",s),s}catch(s){throw c("batchWithdrawMapped",s)}}async withdrawUnmappedBatchByKeys(e){let t=e.dropKeys.filter(r=>r.toLowerCase()!==e.anchorDropKey.toLowerCase()),n=this.batchTransactionOverrides(t.length+1);try{let r=ae(e.claimKey),s=await this.publicClient.readContract({address:this.address,abi:d,functionName:"claimDigest",args:[e.recipient,e.id,e.anchorDropKey]}),p=se(await oe({hash:s,privateKey:e.claimKey})),y=await ne({account:r,chain:this.chain,transport:this.transport}).writeContract({address:this.address,abi:d,functionName:"withdrawUnmappedBatchByKeys",args:[e.recipient,e.id,e.anchorDropKey,p,re(T(e.secret)),e.nonce,e.deadline,t,e.validatorSignature],...n});return await this.confirm("withdrawUnmappedBatchByKeys",y),y}catch(r){throw pe("withdrawUnmappedBatchByKeys",r)}}async getValidatorNonce(e){try{return await this.publicClient.readContract({address:this.address,abi:P,functionName:"validatorNonceById",args:[H(T(e.id))]})}catch(t){throw c("validatorNonceById",t)}}async getValidatorClaimDigest(e){try{return await this.publicClient.readContract({address:this.address,abi:P,functionName:"validatorClaimDigest",args:[e.recipient,e.id,e.nonce,e.deadline]})}catch(t){throw c("validatorClaimDigest",t)}}async getValidator(){try{return await this.publicClient.readContract({address:this.address,abi:P,functionName:"validator"})}catch(e){throw c("validator",e)}}async getClaimedRecipient(e){try{return await this.publicClient.readContract({address:this.address,abi:d,functionName:"claimedRecipientOf",args:[e.id]})}catch(t){throw c("claimedRecipientOf",t)}}async refundByKey(e){let t=this.requireAccount();try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"refund",args:[e.dropKey],account:t});let n=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"refund",args:[e.dropKey],account:t,chain:this.chain,...this.transactionOverrides()});return await this.confirm("refund",n),n}catch(n){throw c("refund",n)}}async getChangeNonce(e){try{return await this.publicClient.readContract({address:this.address,abi:d,functionName:"changeNonceById",args:[H(T(e.id))]})}catch(t){throw c("changeNonceById",t)}}async getPendingRecipientChange(e){try{return await this.publicClient.readContract({address:this.address,abi:d,functionName:"pendingRecipientChange",args:[H(T(e.id))]})}catch(t){throw c("pendingRecipientChange",t)}}async requestRecipientChange(e){return this.currentContractWrite("requestRecipientChange",[e.id,e.newRecipient])}async completeRecipientChange(e){return this.currentContractWrite("completeRecipientChange",[e.id,e.nonce,e.deadline,e.signature])}async cancelRecipientChange(e){return this.currentContractWrite("cancelRecipientChange",[e.id])}async resetRecipient(e){let t=this.requireAccount();try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:"resetRecipient",args:[e.id,e.nonce,e.deadline,e.signature],account:t});let n=await this.walletClient.writeContract({address:this.address,abi:d,functionName:"resetRecipient",args:[e.id,e.nonce,e.deadline,e.signature],account:t,chain:this.chain,...this.transactionOverrides()});return await this.confirm("resetRecipient",n),n}catch(n){throw c("resetRecipient",n)}}async currentContractWrite(e,t){let n=this.requireAccount();try{await this.publicClient.simulateContract({address:this.address,abi:d,functionName:e,args:t,account:n});let r=await this.walletClient.writeContract({address:this.address,abi:d,functionName:e,args:t,account:n,chain:this.chain,...this.transactionOverrides()});return await this.confirm(e,r),r}catch(r){throw c(e,r)}}transactionOverrides(e=this.transactionFees.gas){return{type:"eip1559",gas:e,maxFeePerGas:this.transactionFees.maxFeePerGas,maxPriorityFeePerGas:this.transactionFees.maxPriorityFeePerGas}}batchTransactionOverrides(e){if(!Number.isSafeInteger(e)||e<=0)throw new a("INVALID_PARAM","batch count must be a positive safe integer");let t=this.transactionFees.batchBaseGas+this.transactionFees.batchGasPerDrop*BigInt(e);if(t>this.transactionFees.maxBatchGas)throw new a("INVALID_PARAM","batch gas exceeds maxBatchGas",{count:e,gas:t.toString(),maxBatchGas:this.transactionFees.maxBatchGas.toString()});return this.transactionOverrides(t)}async sponsorWrite(e,t){try{let n=await t();return await this.confirm(e,n),n}catch(n){throw c(e,n)}}depositedDropKey(e,t,n,r,s){let p=Oe({abi:d,eventName:"Deposited",logs:[...e]}).find(({address:u,args:y})=>u.toLowerCase()===this.address.toLowerCase()&&y.sponsor.toLowerCase()===t.toLowerCase()&&y.amount===n&&y.id===r);if(!p)throw new a("CHAIN_ERROR","deposit receipt omitted the Deposited event",{txHash:s});return p.args.dropKey}async confirm(e,t){let n=await this.publicClient.waitForTransactionReceipt({hash:t});if(n.status!=="success"){let r=await this.recoverRevertName(t,n.blockNumber),s=r?`SafeDrop.${e} reverted: ${r}`:`transaction reverted: ${t}`;throw new a("CHAIN_ERROR",s,{revertName:r,txHash:t})}return n}async recoverRevertName(e,t){try{let n=await this.publicClient.getTransaction({hash:e});await this.publicClient.call({account:n.from,to:n.to??void 0,data:n.input,value:n.value,blockNumber:t});return}catch(n){return B(n)}}requireAccount(){let e=this.walletClient.account;if(!e)throw new a("CHAIN_ERROR","walletClient has no account (connect a wallet first)");return e}};function M(i,e){return{dropKey:i,sponsor:e.sponsor,amount:e.amount,claimAddress:e.claimAddr,recipient:e.recipient,secretHash:e.secretHash,id:e.id}}function c(i,e){if(e instanceof a)return e;let t=B(e),n=e instanceof Error?e.message:String(e),r=t?`SafeDrop.${i} reverted: ${t}`:`SafeDrop.${i} failed`;return new a("CHAIN_ERROR",r,{cause:n,revertName:t})}function pe(i,e){if(e instanceof a)return e;let t=B(e),n=e instanceof ce?e.walk(p=>{let u=p;return typeof u.code=="number"||u.data!==void 0}):void 0,r={revertName:t};typeof n?.code=="number"&&(r.rpcCode=n.code),typeof n?.details=="string"&&(r.rpcMessage=n.details),typeof n?.data=="string"&&(r.rpcData=n.data);let s=t?`SafeDrop.${i} reverted: ${t}`:`SafeDrop.${i} failed`;return new a("CHAIN_ERROR",s,r)}function B(i){if(!(i instanceof ce))return;let e=i.walk(t=>t instanceof te);if(e instanceof te)return e.data?.errorName??e.reason??void 0}var He=BigInt(500),Me=BigInt(1e4),U={dev:{apiBaseUrl:"https://dev-one-pop-api.onechain.nexus/api",contracts:{onePop:"0xfBadB337e634757ca8F8EEB7682acF06bA297d85",permitErc20:"0xFaDAB54449262178aE0562F5D8416bBeF4659714",nft:"0x11ce973082c7B90aB2Fc789949CC04e1F85397ff",nftMinter:"0xfBadB337e634757ca8F8EEB7682acF06bA297d85",validator:"0xF30d8e0544f0b92A6987522f4F696D3915B579b4",feeRecipient:"0xF30d8e0544f0b92A6987522f4F696D3915B579b4"}},stage:{apiBaseUrl:"https://stg-one-pop-api.onechain.nexus/api",contracts:{onePop:"0x4c4599fFa1D83bB9689d9a0C557fF2EB35443949",permitErc20:"0xFaDAB54449262178aE0562F5D8416bBeF4659714",nft:"0x0535fce7113cf48f21C32472bBA929F8F31ab05c",nftMinter:"0x4c4599fFa1D83bB9689d9a0C557fF2EB35443949",validator:"0xa953af3742345dFC2BdcA30cBa79D8313b0a3B61",feeRecipient:"0xa953af3742345dFC2BdcA30cBa79D8313b0a3B61"}},production:{apiBaseUrl:"https://one-pop-api.onechain.nexus/api"}},V={createWallet:"/wallets",dropMetadata:"/drops/metadata",retrievePrivateKey:"/wallets/private-key",drops:"/drops",rejectDrops:"/drops/reject",envelopes:"/envelopes",leaderboards:"/leaderboards",leaderboardMe:"/leaderboards/me",histories:"/histories",xConnections:"/x-connections",batchClaimSignature:"/batch-claim-signature",feedbacks:"/feedbacks",revealYou:"/reveal-you",recipientChangeSignature:"/recipient-change-signature",recipientResetSignature:"/recipient-reset-signature",eventsSubscribe:"/events/subscribe"},Be="https://dev-cross-auth.crosstoken.io";function F(i){try{return import.meta.env?.[i]}catch{return}}function _(i){if(!(typeof process>"u"||!process.env))switch(i){case"NEXT_PUBLIC_ONE_POP_ENVIRONMENT":return process.env.NEXT_PUBLIC_ONE_POP_ENVIRONMENT;case"ONE_POP_ENVIRONMENT":return process.env.ONE_POP_ENVIRONMENT;case"NEXT_PUBLIC_ONE_POP_API_BASE_URL":return process.env.NEXT_PUBLIC_ONE_POP_API_BASE_URL;case"NEXT_PUBLIC_CROSS_AUTH_URL":return process.env.NEXT_PUBLIC_CROSS_AUTH_URL;default:return}}function K(){let i=F("VITE_ONE_POP_ENVIRONMENT")??_("NEXT_PUBLIC_ONE_POP_ENVIRONMENT")??_("ONE_POP_ENVIRONMENT");return Ue(i)}function Ue(i){switch(i?.toLowerCase()){case"dev":case"development":return"dev";case"stg":case"stage":case"staging":return"stage";case void 0:case"production":case"prod":return"production";default:throw new Error(`[pop] Invalid environment: ${i}`)}}function ue(){return U[K()]}function L(){return Ve(K())}function Ve(i){let e=U[i].contracts;if(!e)throw new Error(`[pop] Contract addresses are not configured for ${i}`);return e}function q(){let e=F("VITE_ONE_POP_API_BASE_URL")??_("NEXT_PUBLIC_ONE_POP_API_BASE_URL")??ue().apiBaseUrl;return ye(e),e}function $(){let e=(F("VITE_CROSS_AUTH_URL")??_("NEXT_PUBLIC_CROSS_AUTH_URL")??Be).replace(/\/+$/,"");return ye(e),e}function ye(i){let e;try{e=new URL(i)}catch{throw new Error(`[pop] Invalid base URL: ${i}`)}if(e.protocol==="https:")return;let t=e.hostname==="localhost"||e.hostname==="127.0.0.1"||e.hostname.endsWith(".local");if(!(e.protocol==="http:"&&t))throw new Error(`[pop] base URL must be https (or http://localhost for dev). Got: ${i}`)}var Fe={INVALID_PARAM:"INVALID_PARAM",RATE_LIMITED:"RATE_LIMITED",INVALID_OAUTH_TOKEN:"INVALID_OAUTH_TOKEN",UNAUTHORIZED:"UNAUTHORIZED",WALLET_NOT_FOUND:"WALLET_NOT_FOUND",SEND_BLOCKED:"SEND_BLOCKED",ENVELOPE_NOT_FOUND:"ENVELOPE_NOT_FOUND",PENDING_LIMIT_EXCEEDED:"PENDING_LIMIT_EXCEEDED",DROP_NOT_FOUND:"DROP_NOT_FOUND",IDENTIFIER_NOT_MAPPED:"IDENTIFIER_NOT_MAPPED",X_CONNECTION_NOT_FOUND:"X_CONNECTION_NOT_FOUND",X_ALREADY_CONNECTED:"X_ALREADY_CONNECTED"},v=140,C=class{constructor(e={}){this.baseUrl=(e.baseUrl??q()).replace(/\/+$/,"");let t=e.fetchImpl??globalThis.fetch;if(!t)throw new Error("fetch is unavailable; provide options.fetchImpl");this.fetchImpl=t,this.getJwt=e.getJwt,this.paths={...V,...e.paths}}async createClaimWallet(e){let t=await this.request(this.paths.createWallet,{method:"POST",auth:!0,payload:{identifier:e.recipient.handle,oauth_type:e.recipient.provider,sender_address:e.sender}});if(!t?.address)throw new a("API_ERROR","createClaimWallet: missing address in response",{body:t});if(!t.identifier)throw new a("API_ERROR","createClaimWallet: missing identifier in response",{body:t});return{claimAddress:t.address,id:t.identifier,isMapped:t.is_mapped===!0}}async recordDropMetadata(e){if(e.message&&[...e.message].length>v)throw new a("INVALID_PARAM",`message must be <= ${v} runes`);await this.request(this.paths.dropMetadata,{method:"POST",auth:!0,query:{tx_hash:e.txHash},payload:{...e.message?{message:e.message}:{},...e.envelopeId?{envelope_id:e.envelopeId}:{}}})}async retrieveClaimKey(e){let t=await this.request(this.paths.retrievePrivateKey,{method:"POST",payload:{oauth_token:e.oauth.accessToken,oauth_type:e.oauth.provider,sender_address:e.senderAddress,address:e.claimAddress}});if(t?.private_key&&t.address){if(t.address.toLowerCase()!==e.claimAddress.toLowerCase())throw new a("API_ERROR","retrieveClaimKey: returned a different address");return{isMapped:!1,claimKey:t.private_key,claimAddress:t.address}}if(t?.is_mapped===!0)return{isMapped:!0};throw new a("API_ERROR","retrieveClaimKey: missing key/address in response",{body:t})}async listDrops(e){if(!e?.token)throw new a("INVALID_PARAM","listDrops requires a token address");let t=await this.request(this.paths.drops,{method:"GET",auth:!0,query:{token:e.token,drop_key:e.dropKey}});return{items:(t?.items??[]).map(Le),count:t?.count??0,totalAmount:l(t?.total_amount,"drops.total_amount"),hasClaimedBefore:t?.has_claimed_before===!0,mappedRecipient:h(t?.mapped_recipient),pendingChangeTo:h(t?.pending_change_to)}}async rejectDrops(e){if(!Array.isArray(e.dropIds)||e.dropIds.length===0||e.dropIds.length>100||e.dropIds.some(n=>!Number.isSafeInteger(n)||n<=0))throw new a("INVALID_PARAM","dropIds must contain 1-100 positive integers");return(await this.request(this.paths.rejectDrops,{method:"POST",auth:!0,payload:{drop_ids:e.dropIds}}))?.count??0}async listEnvelopes(e={}){return((await this.request(this.paths.envelopes,{method:"GET",query:{locale:e.locale}}))?.items??[]).map(n=>({id:o(n.id),name:o(n.name),imageUrl:o(n.image_url),badge:o(n.badge),sortOrder:Number(n.sort_order??0)}))}async getLeaderboard(e){if(!e.token)throw new a("INVALID_PARAM","getLeaderboard requires a token address");let t=await this.request(this.paths.leaderboards,{method:"GET",query:{token:e.token,page:e.page,page_size:e.pageSize,identifier:e.identifier}});return{items:(t?.items??[]).map(me),page:t?.page??1,pageSize:t?.page_size??0,total:t?.total??0}}async getMyLeaderboardEntry(e){let t=await this.request(this.paths.leaderboardMe,{method:"GET",auth:!0,query:{token:e.token}});return{...me(t??{}),rank:fe(t?.rank)}}async listHistories(e){if(!e?.type)throw new a("INVALID_PARAM","listHistories requires type");let t=await this.request(this.paths.histories,{method:"GET",auth:!0,query:{type:e.type,token:e.token,status:e.status,rejected:e.rejected===void 0?void 0:String(e.rejected),page:e.page,page_size:e.pageSize}});return{items:(t?.items??[]).map(n=>({id:Number(n.id??0),type:o(n.type),status:o(n.status),token:o(n.token),amount:l(n.amount,"history.amount"),claimAddress:o(n.claim_address),depositTxHash:o(n.deposit_tx_hash),depositedAt:o(n.deposited_at),resolvedTxHash:h(n.resolved_tx_hash),resolvedAt:h(n.resolved_at),message:o(n.message),feedback:h(n.feedback),envelopeId:o(n.envelope_id),rejected:n.rejected===!0,sender:be(n.sender),receiver:qe(n.receiver)})),page:t?.page??1,pageSize:t?.page_size??0,total:t?.total??0}}async getXConnection(){let e=await this.request(this.paths.xConnections,{method:"GET",auth:!0,notFoundAsNull:!0});return e?le(e):null}async connectX(e){let t=await this.request(this.paths.xConnections,{method:"POST",auth:!0,payload:{oauth_token:e.oauth.accessToken}});return le(t??{})}async disconnectX(){await this.request(this.paths.xConnections,{method:"DELETE",auth:!0,notFoundAsNull:!0})}async submitFeedback(e){if(!Number.isSafeInteger(e.dropId)||e.dropId<=0)throw new a("INVALID_PARAM","dropId must be a positive integer");if(!e.message.trim()||[...e.message.trim()].length>v)throw new a("INVALID_PARAM",`message must be 1-${v} runes`);let t=await this.request(this.paths.feedbacks,{method:"PUT",auth:!0,query:{drop_id:e.dropId},payload:{message:e.message}});return o(t?.message)}async setRevealYou(e){return(await this.request(this.paths.revealYou,{method:"PUT",auth:!0,payload:{reveal_you:e.revealYou}}))?.reveal_you===!0}async requestRecipientChangeSignature(e){let t=await this.request(this.paths.recipientChangeSignature,{method:"POST",auth:!0,payload:he(e)});return{...ge(t,e),newRecipient:o(t?.new_recipient)}}async requestRecipientResetSignature(e){let t=await this.request(this.paths.recipientResetSignature,{method:"POST",payload:he(e)});return ge(t,e)}async requestBatchClaimSignature(e){let t=await this.request(this.paths.batchClaimSignature,{method:"POST",auth:!0,payload:{id:e.id,oauth_token:e.oauth.accessToken,nonce:e.nonce.toString(),deadline:e.deadline.toString()}}),n=o(t?.signature);if(!n)throw new a("API_ERROR","requestBatchClaimSignature: missing signature",{body:t});return{id:o(t?.id)||e.id,recipient:o(t?.recipient),nonce:x(t?.nonce)?l(t?.nonce,"batchClaim.nonce"):e.nonce,deadline:x(t?.deadline)?l(t?.deadline,"batchClaim.deadline"):e.deadline,signature:n}}async request(e,t){let n={};if(t.payload&&(n["Content-Type"]="application/json"),t.auth){let s=await this.getJwt?.();if(!s)throw new a("UNAUTHORIZED",`${e} requires a SIWE JWT (options.getJwt)`);n.Authorization=`Bearer ${s}`}let r;try{r=await this.fetchImpl(`${this.baseUrl}${e}${Ke(t.query)}`,{method:t.method,headers:n,body:t.payload?JSON.stringify(t.payload):void 0})}catch(s){throw new a("API_ERROR",`Network error calling ${e}`,{cause:s instanceof Error?s.message:String(s)})}if(r.status===404&&t.notFoundAsNull)return null;if(!r.ok){let s=await r.json().catch(()=>{}),p=s?.code_name;throw new a((p?Fe[p]:void 0)??"API_ERROR",s?.message?`${e}: ${s.message}`:`${e} responded ${r.status}`,{status:r.status,code:s?.code,codeName:p})}return r.status===204?null:await r.json().catch(()=>null)}};function Ke(i){if(!i)return"";let e=new URLSearchParams;for(let[n,r]of Object.entries(i))r!==void 0&&r!==""&&e.set(n,String(r));let t=e.toString();return t?`?${t}`:""}function x(i){return i!=null&&i!==""}function o(i){return typeof i=="string"?i:""}function h(i){return typeof i=="string"&&i?i:null}function l(i,e){if(typeof i=="bigint")return i;if(typeof i=="number"){if(!Number.isSafeInteger(i))throw new a("API_ERROR",`${e} exceeds safe-integer precision as a JSON number`,{value:i});return BigInt(i)}let t=typeof i=="string"?i.trim():"";if(!t)return BigInt(0);try{return BigInt(t)}catch{throw new a("API_ERROR",`${e} is not a valid decimal string`,{value:i})}}function Le(i){let e=i??{},t=e.sender??{};return{id:Number(e.id??0),dropKey:o(e.drop_key),claimAddress:o(e.claim_address),token:o(e.token),amount:l(e.amount,"drop.amount"),message:o(e.message),envelopeId:o(e.envelope_id),depositedAt:o(e.deposited_at),rejected:e.rejected===!0,sender:{address:o(t.address),handle:o(t.handle),displayName:o(t.display_name),profileImageUrl:o(t.profile_image_url)}}}function le(i){return{xUserId:o(i.x_user_id),handle:o(i.handle),displayName:o(i.display_name),profileImageUrl:o(i.profile_image_url),walletAddress:o(i.wallet_address),revealYou:i.reveal_you===!0,onchainMapped:i.onchain_mapped===!0,mappedRecipient:h(i.mapped_recipient)}}function me(i){return{identifier:o(i.identifier),balance:l(i.balance,"leaderboard.balance"),lastDepositAmount:l(i.last_deposit_amount,"leaderboard.last_deposit_amount"),rank:Number(i.rank??0),previousRank:fe(i.previous_rank),profileImageUrl:o(i.profile_image_url)}}function fe(i){return typeof i=="number"?i:null}function be(i){let e=i??{};return{address:o(e.address),handle:o(e.handle),displayName:o(e.display_name),profileImageUrl:o(e.profile_image_url)}}function qe(i){return{...be(i),address:h(i?.address)}}function he(i){return{id:i.id,oauth_token:i.oauth.accessToken,nonce:i.nonce.toString(),deadline:i.deadline.toString()}}function ge(i,e){let t=o(i?.signature);if(!t)throw new a("API_ERROR","signature response is missing signature");return{id:o(i?.id)||e.id,nonce:x(i?.nonce)?l(i?.nonce,"signature.nonce"):e.nonce,deadline:x(i?.deadline)?l(i?.deadline,"signature.deadline"):e.deadline,signature:t}}var we=[{type:"constructor",inputs:[{name:"token_",type:"address",internalType:"contract IERC20"},{name:"validator_",type:"address",internalType:"address"},{name:"sbt_",type:"address",internalType:"contract ISoulboundToken"}],stateMutability:"nonpayable"},{type:"function",name:"MAX_PENDING_PER_SPONSOR_ID",inputs:[],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"activeDropOf",inputs:[{name:"sponsor",type:"address",internalType:"address"},{name:"claimAddr",type:"address",internalType:"address"}],outputs:[{name:"",type:"bytes32",internalType:"bytes32"}],stateMutability:"view"},{type:"function",name:"batchWithdrawMapped",inputs:[{name:"dropKeys",type:"bytes32[]",internalType:"bytes32[]"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"batchWithdrawMapped",inputs:[{name:"count",type:"uint256",internalType:"uint256"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"cancelRecipientChange",inputs:[{name:"id",type:"string",internalType:"string"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"changeNonceById",inputs:[{name:"idKey",type:"bytes32",internalType:"bytes32"}],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"changeRecipientDigest",inputs:[{name:"id",type:"string",internalType:"string"},{name:"newRecipient",type:"address",internalType:"address"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"}],outputs:[{name:"",type:"bytes32",internalType:"bytes32"}],stateMutability:"view"},{type:"function",name:"claimDigest",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"},{name:"dropKey",type:"bytes32",internalType:"bytes32"}],outputs:[{name:"",type:"bytes32",internalType:"bytes32"}],stateMutability:"view"},{type:"function",name:"claimedRecipientOf",inputs:[{name:"id",type:"string",internalType:"string"}],outputs:[{name:"",type:"address",internalType:"address"}],stateMutability:"view"},{type:"function",name:"completeRecipientChange",inputs:[{name:"id",type:"string",internalType:"string"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"},{name:"validatorSignature",type:"bytes",internalType:"bytes"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"deposit",inputs:[{name:"claimAddr",type:"address",internalType:"address"},{name:"amount",type:"uint256",internalType:"uint256"},{name:"id",type:"string",internalType:"string"},{name:"secretHash",type:"bytes32",internalType:"bytes32"},{name:"permitDeadline",type:"uint256",internalType:"uint256"},{name:"v",type:"uint8",internalType:"uint8"},{name:"r",type:"bytes32",internalType:"bytes32"},{name:"s",type:"bytes32",internalType:"bytes32"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"depositMapped",inputs:[{name:"amount",type:"uint256",internalType:"uint256"},{name:"id",type:"string",internalType:"string"},{name:"permitDeadline",type:"uint256",internalType:"uint256"},{name:"v",type:"uint8",internalType:"uint8"},{name:"r",type:"bytes32",internalType:"bytes32"},{name:"s",type:"bytes32",internalType:"bytes32"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"drops",inputs:[{name:"dropKey",type:"bytes32",internalType:"bytes32"}],outputs:[{name:"sponsor",type:"address",internalType:"address"},{name:"amount",type:"uint96",internalType:"uint96"},{name:"claimAddr",type:"address",internalType:"address"},{name:"recipient",type:"address",internalType:"address"},{name:"secretHash",type:"bytes32",internalType:"bytes32"},{name:"id",type:"string",internalType:"string"}],stateMutability:"view"},{type:"function",name:"eip712Domain",inputs:[],outputs:[{name:"fields",type:"bytes1",internalType:"bytes1"},{name:"name",type:"string",internalType:"string"},{name:"version",type:"string",internalType:"string"},{name:"chainId",type:"uint256",internalType:"uint256"},{name:"verifyingContract",type:"address",internalType:"address"},{name:"salt",type:"bytes32",internalType:"bytes32"},{name:"extensions",type:"uint256[]",internalType:"uint256[]"}],stateMutability:"view"},{type:"function",name:"pendingCountOf",inputs:[{name:"sponsor",type:"address",internalType:"address"}],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"pendingCountOf",inputs:[{name:"sponsor",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"}],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"pendingDropsByRecipient",inputs:[{name:"recipient",type:"address",internalType:"address"}],outputs:[{name:"dropKeys",type:"bytes32[]",internalType:"bytes32[]"},{name:"records",type:"tuple[]",internalType:"struct ONEpop.Drop[]",components:[{name:"sponsor",type:"address",internalType:"address"},{name:"amount",type:"uint96",internalType:"uint96"},{name:"claimAddr",type:"address",internalType:"address"},{name:"recipient",type:"address",internalType:"address"},{name:"secretHash",type:"bytes32",internalType:"bytes32"},{name:"id",type:"string",internalType:"string"}]}],stateMutability:"view"},{type:"function",name:"pendingDropsByXid",inputs:[{name:"id",type:"string",internalType:"string"}],outputs:[{name:"dropKeys",type:"bytes32[]",internalType:"bytes32[]"},{name:"records",type:"tuple[]",internalType:"struct ONEpop.Drop[]",components:[{name:"sponsor",type:"address",internalType:"address"},{name:"amount",type:"uint96",internalType:"uint96"},{name:"claimAddr",type:"address",internalType:"address"},{name:"recipient",type:"address",internalType:"address"},{name:"secretHash",type:"bytes32",internalType:"bytes32"},{name:"id",type:"string",internalType:"string"}]}],stateMutability:"view"},{type:"function",name:"pendingDropsOf",inputs:[{name:"sponsor",type:"address",internalType:"address"}],outputs:[{name:"dropKeys",type:"bytes32[]",internalType:"bytes32[]"},{name:"records",type:"tuple[]",internalType:"struct ONEpop.Drop[]",components:[{name:"sponsor",type:"address",internalType:"address"},{name:"amount",type:"uint96",internalType:"uint96"},{name:"claimAddr",type:"address",internalType:"address"},{name:"recipient",type:"address",internalType:"address"},{name:"secretHash",type:"bytes32",internalType:"bytes32"},{name:"id",type:"string",internalType:"string"}]}],stateMutability:"view"},{type:"function",name:"pendingRecipientChange",inputs:[{name:"idKey",type:"bytes32",internalType:"bytes32"}],outputs:[{name:"newRecipient",type:"address",internalType:"address"}],stateMutability:"view"},{type:"function",name:"refund",inputs:[{name:"dropKey",type:"bytes32",internalType:"bytes32"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"requestRecipientChange",inputs:[{name:"id",type:"string",internalType:"string"},{name:"newRecipient",type:"address",internalType:"address"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"resetRecipient",inputs:[{name:"id",type:"string",internalType:"string"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"},{name:"validatorSignature",type:"bytes",internalType:"bytes"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"resetRecipientDigest",inputs:[{name:"id",type:"string",internalType:"string"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"}],outputs:[{name:"",type:"bytes32",internalType:"bytes32"}],stateMutability:"view"},{type:"function",name:"sbt",inputs:[],outputs:[{name:"",type:"address",internalType:"contract ISoulboundToken"}],stateMutability:"view"},{type:"function",name:"settledCountOf",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"}],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"token",inputs:[],outputs:[{name:"",type:"address",internalType:"contract IERC20"}],stateMutability:"view"},{type:"function",name:"validator",inputs:[],outputs:[{name:"",type:"address",internalType:"address"}],stateMutability:"view"},{type:"function",name:"validatorClaimDigest",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"}],outputs:[{name:"",type:"bytes32",internalType:"bytes32"}],stateMutability:"view"},{type:"function",name:"validatorNonceById",inputs:[{name:"idKey",type:"bytes32",internalType:"bytes32"}],outputs:[{name:"",type:"uint256",internalType:"uint256"}],stateMutability:"view"},{type:"function",name:"withdrawMapped",inputs:[{name:"dropKey",type:"bytes32",internalType:"bytes32"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"withdrawUnmapped",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"},{name:"dropKey",type:"bytes32",internalType:"bytes32"},{name:"signature",type:"bytes",internalType:"bytes"},{name:"secret",type:"bytes",internalType:"bytes"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"withdrawUnmappedBatch",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"},{name:"anchorDropKey",type:"bytes32",internalType:"bytes32"},{name:"signature",type:"bytes",internalType:"bytes"},{name:"secret",type:"bytes",internalType:"bytes"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"},{name:"payCount",type:"uint256",internalType:"uint256"},{name:"moveCount",type:"uint256",internalType:"uint256"},{name:"validatorSignature",type:"bytes",internalType:"bytes"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"withdrawUnmappedBatchByKeys",inputs:[{name:"recipient",type:"address",internalType:"address"},{name:"id",type:"string",internalType:"string"},{name:"anchorDropKey",type:"bytes32",internalType:"bytes32"},{name:"signature",type:"bytes",internalType:"bytes"},{name:"secret",type:"bytes",internalType:"bytes"},{name:"nonce",type:"uint256",internalType:"uint256"},{name:"deadline",type:"uint256",internalType:"uint256"},{name:"dropKeys",type:"bytes32[]",internalType:"bytes32[]"},{name:"validatorSignature",type:"bytes",internalType:"bytes"}],outputs:[],stateMutability:"nonpayable"},{type:"event",name:"Deposited",inputs:[{name:"addr",type:"address",indexed:!0,internalType:"address"},{name:"sponsor",type:"address",indexed:!0,internalType:"address"},{name:"dropKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"amount",type:"uint256",indexed:!1,internalType:"uint256"},{name:"id",type:"string",indexed:!1,internalType:"string"},{name:"secretHash",type:"bytes32",indexed:!1,internalType:"bytes32"},{name:"token",type:"address",indexed:!1,internalType:"address"}],anonymous:!1},{type:"event",name:"EIP712DomainChanged",inputs:[],anonymous:!1},{type:"event",name:"Moved",inputs:[{name:"claimAddr",type:"address",indexed:!0,internalType:"address"},{name:"recipient",type:"address",indexed:!0,internalType:"address"},{name:"dropKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"sponsor",type:"address",indexed:!1,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"},{name:"amount",type:"uint256",indexed:!1,internalType:"uint256"}],anonymous:!1},{type:"event",name:"RecipientChangeCancelled",inputs:[{name:"idKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"from",type:"address",indexed:!0,internalType:"address"},{name:"to",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"}],anonymous:!1},{type:"event",name:"RecipientChangeRequested",inputs:[{name:"idKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"from",type:"address",indexed:!0,internalType:"address"},{name:"to",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"}],anonymous:!1},{type:"event",name:"RecipientChanged",inputs:[{name:"idKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"from",type:"address",indexed:!0,internalType:"address"},{name:"to",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"}],anonymous:!1},{type:"event",name:"RecipientMapped",inputs:[{name:"idKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"recipient",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"}],anonymous:!1},{type:"event",name:"RecipientReset",inputs:[{name:"idKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"from",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"}],anonymous:!1},{type:"event",name:"Refunded",inputs:[{name:"claimAddr",type:"address",indexed:!0,internalType:"address"},{name:"sponsor",type:"address",indexed:!0,internalType:"address"},{name:"dropKey",type:"bytes32",indexed:!0,internalType:"bytes32"},{name:"id",type:"string",indexed:!1,internalType:"string"},{name:"amount",type:"uint256",indexed:!1,internalType:"uint256"},{name:"token",type:"address",indexed:!1,internalType:"address"}],anonymous:!1},{type:"event",name:"Withdrawn",inputs:[{name:"claimAddr",type:"address",indexed:!0,internalType:"address"},{name:"recipient",type:"address",indexed:!0,internalType:"address"},{name:"sponsor",type:"address",indexed:!0,internalType:"address"},{name:"id",type:"string",indexed:!1,internalType:"string"},{name:"amount",type:"uint256",indexed:!1,internalType:"uint256"},{name:"token",type:"address",indexed:!1,internalType:"address"},{name:"sbtTokenId",type:"uint256",indexed:!1,internalType:"uint256"},{name:"dropKey",type:"bytes32",indexed:!1,internalType:"bytes32"}],anonymous:!1},{type:"error",name:"AlreadyMapped",inputs:[]},{type:"error",name:"AmountOverflow",inputs:[]},{type:"error",name:"ChangeAlreadyRequested",inputs:[]},{type:"error",name:"ChangeInProgress",inputs:[]},{type:"error",name:"CountExceedsPending",inputs:[]},{type:"error",name:"DropAlreadyExists",inputs:[]},{type:"error",name:"DropNotFound",inputs:[]},{type:"error",name:"ECDSAInvalidSignature",inputs:[]},{type:"error",name:"ECDSAInvalidSignatureLength",inputs:[{name:"length",type:"uint256",internalType:"uint256"}]},{type:"error",name:"ECDSAInvalidSignatureS",inputs:[{name:"s",type:"bytes32",internalType:"bytes32"}]},{type:"error",name:"EmptyId",inputs:[]},{type:"error",name:"IdMismatch",inputs:[]},{type:"error",name:"IdNotMapped",inputs:[]},{type:"error",name:"InvalidClaimSignature",inputs:[]},{type:"error",name:"InvalidShortString",inputs:[]},{type:"error",name:"InvalidValidatorNonce",inputs:[]},{type:"error",name:"InvalidValidatorSignature",inputs:[]},{type:"error",name:"NoPendingChange",inputs:[]},{type:"error",name:"NotRecipient",inputs:[]},{type:"error",name:"NotSponsor",inputs:[]},{type:"error",name:"PendingLimitExceeded",inputs:[]},{type:"error",name:"RecipientNotEmpty",inputs:[]},{type:"error",name:"ReentrancyGuardReentrantCall",inputs:[]},{type:"error",name:"SafeERC20FailedOperation",inputs:[{name:"token",type:"address",internalType:"address"}]},{type:"error",name:"SameRecipient",inputs:[]},{type:"error",name:"SecretMismatch",inputs:[]},{type:"error",name:"StringTooLong",inputs:[{name:"str",type:"string",internalType:"string"}]},{type:"error",name:"ValidatorSigExpired",inputs:[]},{type:"error",name:"ZeroAmount",inputs:[]},{type:"error",name:"ZeroClaimAddress",inputs:[]},{type:"error",name:"ZeroCount",inputs:[]},{type:"error",name:"ZeroRecipient",inputs:[]},{type:"error",name:"ZeroSbt",inputs:[]},{type:"error",name:"ZeroSecretHash",inputs:[]},{type:"error",name:"ZeroToken",inputs:[]},{type:"error",name:"ZeroValidator",inputs:[]}];var Xe=we;var X=class{constructor(e={}){this.baseUrl=(e.baseUrl??$()).replace(/\/+$/,""),this.domain=e.domain??globalThis.location?.origin??"";let t=e.fetchImpl??globalThis.fetch;if(!t)throw new Error("fetch is unavailable; provide options.fetchImpl");this.fetchImpl=t}unsignedHash(e,t){return this.post("/login/unsigned-hash",{chain_id:e,address:t,domain:this.domain})}siweToken(e,t){return this.post("/login/token",{address:e,signature:t,domain:this.domain})}async post(e,t){let n;try{n=await this.fetchImpl(`${this.baseUrl}/cross-auth${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}catch(s){throw new a("API_ERROR",`cross-auth network error calling ${e}`,{cause:s instanceof Error?s.message:String(s)})}let r=await n.json().catch(()=>({}));if(!n.ok||r.data==null)throw new a("API_ERROR",`cross-auth ${e} failed`,{code:r.code,message:r.message});return r.data}};function Ge(i){let e=i.apiPort??new C(i.api),t=new A({address:i.contractAddress??L().onePop,publicClient:i.publicClient,walletClient:i.walletClient,chain:i.chain,transport:i.transport,withdrawFees:i.withdrawFees,transactionFees:i.transactionFees});return Q({claimBaseUrl:i.claimBaseUrl},{api:e,chain:t,signer:new b,crypto:new f})}async function W(){let i=G(Pe(32)),e=await We().digest("SHA-256",je(i)),t=G(new Uint8Array(e));return{verifier:i,challenge:t,method:"S256"}}function j(){return G(Pe(16))}function Pe(i){let e=globalThis.crypto;if(!e?.getRandomValues)throw new Error("crypto.getRandomValues unavailable");let t=new Uint8Array(i);return e.getRandomValues(t),t}function We(){let i=globalThis.crypto?.subtle;if(!i)throw new Error("crypto.subtle unavailable (needs https/secure context)");return i}function je(i){return new TextEncoder().encode(i)}function G(i){let e="";for(let n of i)e+=String.fromCharCode(n);let t=globalThis.btoa?.(e);if(t===void 0)throw new Error("btoa unavailable");return t.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var z=class{constructor(e={}){this.baseUrl=(e.baseUrl??"").replace(/\/+$/,""),this.tokenPath=e.tokenPath??"/api/x/token",this.mePath=e.mePath??"/api/x/me";let t=e.fetchImpl??globalThis.fetch;if(!t)throw new Error("fetch is unavailable; provide options.fetchImpl");this.fetchImpl=t}async exchangeCode(e){let n=await(await this.call(this.tokenPath,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({clientId:e.clientId,redirectUri:e.redirectUri,code:e.code,verifier:e.codeVerifier})})).json().catch(()=>({}));if(!n.access_token)throw new a("API_ERROR","X token exchange: missing access_token",{body:n});return{accessToken:n.access_token,scope:n.scope,expiresIn:n.expires_in,refreshToken:n.refresh_token}}async getHandle(e){let n=await(await this.call(this.mePath,{method:"GET",headers:{Authorization:`Bearer ${e}`}})).json().catch(()=>({})),r=n.data?.username??n.username;if(!r)throw new a("API_ERROR","X /me: missing username",{body:n});return{handle:r}}async call(e,t){let n;try{n=await this.fetchImpl(`${this.baseUrl}${e}`,t)}catch(r){throw new a("API_ERROR",`Network error calling ${e}`,{cause:r instanceof Error?r.message:String(r)})}if(!n.ok)throw new a("API_ERROR",`${e} responded ${n.status}`,{status:n.status});return n}};var Z="pop.xauth.verifier",Y="pop.xauth.state",ze="https://x.com/i/oauth2/authorize",Ze="tweet.read users.read offline.access",J=class{constructor(e){this.opts={clientId:e.clientId,redirectUri:e.redirectUri,scope:e.scope??Ze,authorizeUrl:e.authorizeUrl??ze,port:e.port,storage:e.storage??Ye()}}async start(){let e=await W(),t=j();this.opts.storage.set(Z,e.verifier),this.opts.storage.set(Y,t);let n=new URLSearchParams({response_type:"code",client_id:this.opts.clientId,redirect_uri:this.opts.redirectUri,scope:this.opts.scope,state:t,code_challenge:e.challenge,code_challenge_method:"S256"});return{authorizeUrl:`${this.opts.authorizeUrl}?${n.toString()}`,state:t}}async complete(e){let t=new URL(e),n=t.searchParams.get("code"),r=t.searchParams.get("state");if(!n)throw new a("API_ERROR","X callback: missing authorization code",{error:t.searchParams.get("error")});let s=this.opts.storage.get(Y);if(!r||!s||r!==s)throw new a("API_ERROR","X callback: state mismatch (possible CSRF)");let p=this.opts.storage.get(Z);if(!p)throw new a("API_ERROR","X callback: missing PKCE verifier (expired session?)");let u=await this.opts.port.exchangeCode({clientId:this.opts.clientId,redirectUri:this.opts.redirectUri,code:n,codeVerifier:p}),{handle:y}=await this.opts.port.getHandle(u.accessToken);return this.opts.storage.remove(Z),this.opts.storage.remove(Y),{oauth:{provider:"x",accessToken:u.accessToken},handle:y}}};function Ye(){let i=globalThis.sessionStorage;if(!i)throw new Error("sessionStorage unavailable; provide options.storage");return{get:e=>i.getItem(e),set:(e,t)=>i.setItem(e,t),remove:e=>i.removeItem(e)}}export{X as CrossAuthClient,V as DEFAULT_POP_API_PATHS,C as HttpSafeDropApiAdapter,z as HttpXAuthAdapter,d as ONEPOP_ABI,Me as ONE_POP_BPS_DENOMINATOR,U as ONE_POP_DEPLOYMENTS,He as ONE_POP_FEE_BPS,Xe as SAFEDROP_ABI,P as SAFEDROP_VALIDATOR_ABI,b as ViemClaimSignerAdapter,f as ViemCryptoAdapter,A as ViemSafeDropChainAdapter,J as XAuthClient,Ge as createSafeDropClient,W as generatePkce,j as generateState,$ as getCrossAuthBaseUrl,q as getOnePopApiBaseUrl,L as getOnePopContracts,ue as getOnePopDeployment,K as getPopEnvironment};
@@ -0,0 +1 @@
1
+ var i=class extends Error{constructor(e,r,n){super(r),this.name="SafeDropError",this.code=e,this.details=n}};function g(a){return a.trim().replace(/^@/,"").toLowerCase()}function w(a){let e=a.baseUrl.replace(/\/$/,""),r=e.includes("?")?"&":"?",n=a.claimAddress?`&claim=${encodeURIComponent(a.claimAddress)}`:"",s=`${e}${r}sender=${encodeURIComponent(a.sender)}${n}`;return a.secret?`${s}#${encodeURIComponent(a.secret)}`:s}function b(a){let e=a.indexOf("#"),r=e===-1?a:a.slice(0,e),n=e===-1?"":a.slice(e+1),s=r.indexOf("?"),d=s===-1?"":r.slice(s+1);return{sender:A(d,"sender"),secret:n?decodeURIComponent(n):null}}function H(a){return`\u{1F381} You've received a one-pop drop! Claim your tokens here: ${a}`}function M(a,e){let r=[`text=${encodeURIComponent(a)}`];return e&&r.push(`recipient_id=${encodeURIComponent(e)}`),`https://x.com/messages/compose?${r.join("&")}`}function A(a,e){if(!a)return null;for(let r of a.split("&")){if(!r)continue;let n=r.indexOf("=");if(decodeURIComponent(n===-1?r:r.slice(0,n))===e)return decodeURIComponent(n===-1?"":r.slice(n+1))}return null}var y=class{constructor(e,r,n,s){this.chain=e;this.api=r;this.crypto=n;this.claimBaseUrl=s}async execute(e){if(!e.sender)throw new i("MISSING_SENDER","sender address is required");if(!e.recipient?.handle)throw new i("MISSING_RECIPIENT","recipient social handle is required");if(!e.token)throw new i("INVALID_TOKEN","token address is required (ERC20 only)");if(e.amount<=0n)throw new i("INVALID_AMOUNT","amount must be a positive BigInt");if(e.message&&[...e.message].length>140)throw new i("INVALID_PARAM","message must be <= 140 runes");let r=g(e.recipient.handle);if(!r)throw new i("MISSING_RECIPIENT","recipient handle normalizes to empty");let n=await this.api.createClaimWallet({sender:e.sender,recipient:{...e.recipient,handle:r}}),s=n.id,d=async m=>{if(this.api.recordDropMetadata)try{await this.api.recordDropMetadata({txHash:m,message:e.message,envelopeId:e.envelopeId})}catch(c){if(c instanceof i&&c.details?.codeName==="ENVELOPE_NOT_FOUND"&&e.envelopeId)try{await this.api.recordDropMetadata({txHash:m,message:e.message})}catch{}}};if(n.isMapped){let{txHash:m,dropKey:c}=await this.chain.depositMapped({token:e.token,amount:e.amount,id:s,onSubmitted:d});return{isMapped:!0,dropKey:c,depositTxHash:m}}let o=e.secret??this.crypto.randomSecret();if(!o)throw new i("MISSING_SECRET","secret is empty");let t=this.crypto.keccak256(o),l={claimAddress:n.claimAddress,token:e.token,amount:e.amount,id:s,secretHash:t,onSubmitted:d},{txHash:h,dropKey:u}=await this.chain.depositWithPermit(l);return{isMapped:!1,dropKey:u,claimAddress:n.claimAddress,secretHash:t,withdrawLink:w({baseUrl:this.claimBaseUrl,sender:e.sender,claimAddress:n.claimAddress,secret:o}),depositTxHash:h}}};var N=BigInt(1800),x=30,f=class{constructor(e,r,n,s=()=>Date.now()){this.chain=e;this.api=r;this.crypto=n;this.now=s}async execute(e){let r=g(e.id);if(!r)throw new i("MISSING_RECIPIENT","batchClaim requires an id");if(!e.claimAddress)throw new i("MISSING_CLAIM_ADDRESS","claim address is required");if(!e.sponsor)throw new i("MISSING_SENDER","sponsor address is required");if(!e.claimKey)throw new i("MISSING_CLAIM_KEY","claim key is required");if(!e.secret)throw new i("MISSING_SECRET","secret is required");if(!this.api.requestBatchClaimSignature)throw new i("API_ERROR","requestBatchClaimSignature is not implemented");if(!this.chain.getValidatorNonce||!this.chain.getValidatorClaimDigest||!this.chain.getValidator)throw new i("CHAIN_ERROR","validator reads are not implemented");let n=await this.chain.getDropKeyByClaimAddress(e.claimAddress,e.sponsor);if(!n)throw new i("DROP_NOT_FOUND","anchor drop not found");let s=await this.chain.getDropByKey(n);if(!s||s.id!==r)throw new i("DROP_NOT_FOUND","anchor drop id does not match");let d=await this.chain.getPendingDropsById({id:r});if(!d.length)throw new i("DROP_NOT_FOUND",`No pending drops for ${r}`);let o=e.maxCount??x;if(!Number.isSafeInteger(o)||o<=0)throw new i("INVALID_PARAM","maxCount must be a positive safe integer");let t=e.deadline??BigInt(Math.floor(this.now()/1e3))+(e.deadlineTtlSeconds??N),l=[],h="",u=BigInt(0);for(;d.length;){let m=await this.chain.getValidatorNonce({id:r}),c=await this.api.requestBatchClaimSignature({id:r,oauth:e.oauth,nonce:m,deadline:t});if(e.recipient&&e.recipient.toLowerCase()!==c.recipient.toLowerCase())throw new i("SIGN_FAILED","validator signature is bound to a different recipient");if(h&&h.toLowerCase()!==c.recipient.toLowerCase())throw new i("SIGN_FAILED","validator recipient changed between batches");h=c.recipient,l.length||(u=c.nonce);let I=await this.chain.getValidatorClaimDigest({recipient:h,id:r,nonce:c.nonce,deadline:c.deadline});await this.assertSignedByValidator(I,c.signature);let R=d.length,C=await this.chain.withdrawUnmappedBatchByKeys({claimKey:e.claimKey,recipient:h,id:r,anchorDropKey:n,secret:e.secret,nonce:c.nonce,deadline:c.deadline,dropKeys:d.slice(0,o).map(P=>P.dropKey).filter(P=>P.toLowerCase()!==n.toLowerCase()),validatorSignature:c.signature});if(l.push(C),d=await this.chain.getPendingDropsById({id:r}),d.length>=R)throw new i("CHAIN_ERROR","batch claim made no progress",{id:r,txHash:C})}return{txHashes:l,recipient:h,id:r,nonce:u,deadline:t}}async assertSignedByValidator(e,r){if(!this.crypto.recoverAddress||!this.chain.getValidator)return;let[n,s]=await Promise.all([this.crypto.recoverAddress({digest:e,signature:r}),this.chain.getValidator()]);if(n.toLowerCase()!==s.toLowerCase())throw new i("SIGN_FAILED","batch-claim signature does not recover to validator")}};var D=class{constructor(e,r){this.chain=e;this.signer=r}async execute(e){if(!e.recipient)throw new i("MISSING_RECIPIENT","recipient address is required");if(!e.claimAddress)throw new i("MISSING_CLAIM_ADDRESS","claim address is required");if(!e.secret)throw new i("MISSING_SECRET","secret is required");if(!e.claimKey)throw new i("MISSING_CLAIM_KEY","claim key is required");if(!e.sponsor)throw new i("MISSING_SENDER","sponsor address is required");let r=await this.chain.getDropKeyByClaimAddress(e.claimAddress,e.sponsor);if(!r)throw new i("DROP_NOT_FOUND",`No drop for claim address ${e.claimAddress}`);let n=await this.chain.getDropByKey(r);if(!n)throw new i("DROP_NOT_FOUND",`No drop for key ${r}`);let s=await this.chain.getClaimDigest({recipient:e.recipient,id:n.id,dropKey:r}),d=await this.signer.signDigest({claimKey:e.claimKey,digest:s});return{txHash:await this.chain.withdrawUnmapped({claimKey:e.claimKey,recipient:e.recipient,id:n.id,dropKey:r,signature:d,secret:e.secret})}}};var S=class{constructor(e){this.chain=e}async execute(e){if(!e.claimAddress)throw new i("MISSING_CLAIM_ADDRESS","claim address is required");if(!e.sponsor)throw new i("MISSING_SENDER","sponsor address is required");let r=await this.chain.getDropKeyByClaimAddress(e.claimAddress,e.sponsor);if(!r)throw new i("DROP_NOT_FOUND",`No drop for claim address ${e.claimAddress}`);return{txHash:await this.chain.refundByKey({dropKey:r})}}};function p(a,e){if(!a)throw new i("API_ERROR",`SafeDropApiPort.${e} is not implemented by the injected api adapter`);return a}function z(a,e){let r=new y(e.chain,e.api,e.crypto,a.claimBaseUrl),n=new D(e.chain,e.signer),s=new S(e.chain),d=new f(e.chain,e.api,e.crypto),{api:o}=e;return{config:a,deposit:t=>r.execute(t),retrieveClaimKey:t=>o.retrieveClaimKey(t),withdraw:t=>n.execute(t),refund:t=>s.execute(t),getDrop:(t,l)=>e.chain.getDrop(t,l),getDropByKey:t=>e.chain.getDropByKey(t),getDropKeyByClaimAddress:(t,l)=>e.chain.getDropKeyByClaimAddress(t,l),getClaimedRecipient:t=>e.chain.getClaimedRecipient({id:t}),getPendingDropsById:t=>e.chain.getPendingDropsById({id:t}),getPendingDropsByRecipient:t=>e.chain.getPendingDropsByRecipient({recipient:t}),getPendingDropsBySponsor:t=>e.chain.getPendingDropsBySponsor({sponsor:t}),withdrawUnmapped:t=>e.chain.withdrawUnmapped(t),withdrawMapped:t=>e.chain.withdrawMapped(t),batchWithdrawMapped:t=>e.chain.batchWithdrawMapped({count:t}),batchWithdrawMappedByKeys:t=>e.chain.batchWithdrawMappedByKeys({dropKeys:t}),refundByKey:t=>e.chain.refundByKey({dropKey:t}),getChangeNonce:t=>e.chain.getChangeNonce({id:t}),getPendingRecipientChange:t=>e.chain.getPendingRecipientChange({id:t}),requestRecipientChange:(t,l)=>e.chain.requestRecipientChange({id:t,newRecipient:l}),completeRecipientChange:t=>e.chain.completeRecipientChange(t),cancelRecipientChange:t=>e.chain.cancelRecipientChange({id:t}),resetRecipient:t=>e.chain.resetRecipient(t),listDrops:t=>p(o.listDrops,"listDrops").call(o,t),rejectDrops:t=>p(o.rejectDrops,"rejectDrops").call(o,{dropIds:t}),listEnvelopes:t=>p(o.listEnvelopes,"listEnvelopes").call(o,t),getLeaderboard:t=>p(o.getLeaderboard,"getLeaderboard").call(o,t),getMyLeaderboardEntry:t=>p(o.getMyLeaderboardEntry,"getMyLeaderboardEntry").call(o,t),listHistories:t=>p(o.listHistories,"listHistories").call(o,t),getXConnection:()=>p(o.getXConnection,"getXConnection").call(o),connectX:t=>p(o.connectX,"connectX").call(o,t),disconnectX:()=>p(o.disconnectX,"disconnectX").call(o),submitFeedback:t=>p(o.submitFeedback,"submitFeedback").call(o,t),setRevealYou:t=>p(o.setRevealYou,"setRevealYou").call(o,{revealYou:t}),requestRecipientChangeSignature:t=>p(o.requestRecipientChangeSignature,"requestRecipientChangeSignature").call(o,t),requestRecipientResetSignature:t=>p(o.requestRecipientResetSignature,"requestRecipientResetSignature").call(o,t),batchClaim:t=>d.execute(t),requestBatchClaimSignature:t=>p(o.requestBatchClaimSignature,"requestBatchClaimSignature").call(o,t)}}export{i as a,g as b,w as c,b as d,H as e,M as f,y as g,f as h,D as i,S as j,z as k};
@@ -40,6 +40,8 @@ interface DepositParams {
40
40
  }
41
41
  interface UnmappedDepositResult {
42
42
  readonly isMapped: false;
43
+ /** deposit의 Deposited 이벤트가 확정한 bytes32 drop key. */
44
+ readonly dropKey: Hex;
43
45
  /** 컨트랙트에 커밋된 임시 claim 지갑 주소 = 이 드롭의 키. */
44
46
  readonly claimAddress: Address;
45
47
  readonly secretHash: SecretHash;
@@ -49,6 +51,8 @@ interface UnmappedDepositResult {
49
51
  }
50
52
  interface MappedDepositResult {
51
53
  readonly isMapped: true;
54
+ /** depositMapped의 Deposited 이벤트가 확정한 bytes32 drop key. */
55
+ readonly dropKey: Hex;
52
56
  readonly depositTxHash: Hex;
53
57
  }
54
58
  type DepositResult = UnmappedDepositResult | MappedDepositResult;
@@ -111,14 +115,14 @@ interface BatchClaimResult {
111
115
  readonly nonce: bigint;
112
116
  readonly deadline: bigint;
113
117
  }
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';
118
+ 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' | 'X_ALREADY_CONNECTED';
115
119
  declare class SafeDropError extends Error {
116
120
  readonly code: SafeDropErrorCode;
117
121
  readonly details?: Record<string, unknown>;
118
122
  constructor(code: SafeDropErrorCode, message: string, details?: Record<string, unknown>);
119
123
  }
120
124
 
121
- /** GET/POST /x-connections — X 계정 ↔ 지갑 매핑 (최신 연결이 이긴다). */
125
+ /** GET/POST /x-connections — X 계정 ↔ 지갑 매핑 (계정당 활성 연결 하나). */
122
126
  interface XConnection {
123
127
  readonly xUserId: string;
124
128
  readonly handle: string;
@@ -153,6 +157,8 @@ interface PendingDrop {
153
157
  readonly envelopeId: string;
154
158
  /** RFC3339 문자열. */
155
159
  readonly depositedAt: string;
160
+ /** 인박스 합계에서는 제외되지만 items에는 남는 표시 전용 거절 상태. */
161
+ readonly rejected: boolean;
156
162
  readonly sender: DropSender;
157
163
  }
158
164
  /** GET /drops — 수령 대기 인박스 (Bearer JWT + 활성 X 연결 필요). */
@@ -166,11 +172,6 @@ interface DropInbox {
166
172
  readonly mappedRecipient: Address | null;
167
173
  readonly pendingChangeTo: Address | null;
168
174
  }
169
- /** GET /drops/rejected — 사용자가 숨긴 pending 드롭 목록. */
170
- interface RejectedDrops {
171
- readonly items: readonly PendingDrop[];
172
- readonly count: number;
173
- }
174
175
  /** GET /envelopes — 카드 디자인. 공개 엔드포인트. */
175
176
  interface Envelope {
176
177
  readonly id: string;
@@ -200,17 +201,22 @@ interface MyLeaderboardEntry extends Omit<LeaderboardEntry, 'rank'> {
200
201
  readonly rank: number | null;
201
202
  }
202
203
  type HistoryType = 'sent' | 'received';
204
+ type HistoryStatus = 'pending' | 'claimed' | 'refunded';
203
205
  interface HistoryParty {
204
206
  readonly address: Address;
205
207
  readonly handle: string;
206
208
  readonly displayName: string;
207
209
  readonly profileImageUrl: string;
208
210
  }
211
+ interface HistoryReceiverParty extends Omit<HistoryParty, 'address'> {
212
+ /** 미수령 상태에서는 아직 claiming wallet이 없다. */
213
+ readonly address: Address | null;
214
+ }
209
215
  /** GET /histories의 drop 중심 항목. */
210
216
  interface HistoryEntry {
211
217
  readonly id: number;
212
218
  readonly type: HistoryType;
213
- readonly status: string;
219
+ readonly status: HistoryStatus;
214
220
  readonly token: Address;
215
221
  readonly amount: bigint;
216
222
  readonly claimAddress: Address;
@@ -221,8 +227,10 @@ interface HistoryEntry {
221
227
  readonly message: string;
222
228
  readonly feedback: string | null;
223
229
  readonly envelopeId: string;
230
+ /** 수신자가 인박스에서 숨긴 드롭인지 여부. 온체인 status에는 영향이 없다. */
231
+ readonly rejected: boolean;
224
232
  readonly sender: HistoryParty;
225
- readonly receiver: HistoryParty;
233
+ readonly receiver: HistoryReceiverParty;
226
234
  }
227
235
  interface HistoryPage {
228
236
  readonly items: readonly HistoryEntry[];
@@ -317,15 +325,14 @@ interface SafeDropApiPort {
317
325
  claimAddress: Address;
318
326
  }>;
319
327
  /** GET /drops — 내게 온 수령 대기 목록. Bearer JWT + 활성 X 연결 필요. */
320
- listDrops?(params?: {
321
- token?: Address;
328
+ listDrops?(params: {
329
+ token: Address;
330
+ dropKey?: Hex;
322
331
  }): Promise<DropInbox>;
323
332
  /** POST /drops/reject — 선택한 pending 드롭을 인박스에서 숨긴다. */
324
333
  rejectDrops?(params: {
325
334
  dropIds: readonly number[];
326
335
  }): Promise<number>;
327
- /** GET /drops/rejected — 사용자가 숨긴 pending 드롭 목록. */
328
- listRejectedDrops?(): Promise<RejectedDrops>;
329
336
  /** GET /envelopes — 카드 디자인 목록. 공개(인증 불필요). */
330
337
  listEnvelopes?(params?: {
331
338
  locale?: string;
@@ -344,6 +351,9 @@ interface SafeDropApiPort {
344
351
  listHistories?(params: {
345
352
  type: HistoryType;
346
353
  token?: Address;
354
+ status?: HistoryStatus;
355
+ /** received에서만 적용되며 sent에서는 서버가 무시한다. */
356
+ rejected?: boolean;
347
357
  /** 1-based (기본 1). */
348
358
  page?: number;
349
359
  /** 기본 20, 최대 100. */
@@ -351,7 +361,7 @@ interface SafeDropApiPort {
351
361
  }): Promise<HistoryPage>;
352
362
  /** GET /x-connections — 활성 X 연결. 없으면 null(404를 에러로 던지지 않는다). */
353
363
  getXConnection?(): Promise<XConnection | null>;
354
- /** POST /x-connections — X 계정을 SIWE 지갑에 연결(최신 연결이 이긴다). */
364
+ /** POST /x-connections — X 계정을 SIWE 지갑에 연결. 다른 활성 지갑이 있으면 실패한다. */
355
365
  connectX?(params: {
356
366
  oauth: OAuthProof;
357
367
  }): Promise<XConnection>;
@@ -447,6 +457,7 @@ interface SafeDropChainPort {
447
457
  onSubmitted?: (txHash: Hex) => void | Promise<void>;
448
458
  }): Promise<{
449
459
  txHash: Hex;
460
+ dropKey: Hex;
450
461
  }>;
451
462
  depositMapped(params: {
452
463
  token: Address;
@@ -455,6 +466,7 @@ interface SafeDropChainPort {
455
466
  onSubmitted?: (txHash: Hex) => void | Promise<void>;
456
467
  }): Promise<{
457
468
  txHash: Hex;
469
+ dropKey: Hex;
458
470
  }>;
459
471
  withdrawUnmapped(params: {
460
472
  claimKey: Hex;
@@ -605,13 +617,12 @@ interface SafeDrop {
605
617
  cancelRecipientChange(id: Id): Promise<Hex>;
606
618
  resetRecipient(params: Parameters<SafeDropChainPort['resetRecipient']>[0]): Promise<Hex>;
607
619
  /** 내게 온 수령 대기 목록. Bearer JWT + 활성 X 연결 필요. */
608
- listDrops(params?: {
609
- token?: Address;
620
+ listDrops(params: {
621
+ token: Address;
622
+ dropKey?: Hex;
610
623
  }): Promise<DropInbox>;
611
624
  /** 선택한 pending 드롭을 인박스에서 숨긴다. */
612
625
  rejectDrops(dropIds: readonly number[]): Promise<number>;
613
- /** 사용자가 숨긴 pending 드롭 목록. */
614
- listRejectedDrops(): Promise<RejectedDrops>;
615
626
  /** 카드 디자인 목록 (공개). deposit의 `envelopeId`에 쓴다. */
616
627
  listEnvelopes(params?: {
617
628
  locale?: string;
@@ -630,6 +641,8 @@ interface SafeDrop {
630
641
  listHistories(params: {
631
642
  type: HistoryType;
632
643
  token?: Address;
644
+ status?: HistoryStatus;
645
+ rejected?: boolean;
633
646
  page?: number;
634
647
  pageSize?: number;
635
648
  }): Promise<HistoryPage>;
@@ -676,4 +689,4 @@ interface SafeDrop {
676
689
  }
677
690
  declare function createSafeDrop(config: SafeDropConfig, deps: SafeDropDeps): SafeDrop;
678
691
 
679
- export { type Address as A, type BatchClaimParams as B, type CryptoPort as C, type DepositParams as D, type Envelope as E, type SecretHash as F, type SocialIdentifier as G, type Hex as H, type Id as I, type SocialProvider as J, createSafeDrop as K, 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 RejectedDrops as u, type SafeDrop as v, type SafeDropConfig as w, type SafeDropDeps as x, SafeDropError as y, type SafeDropErrorCode as z };
692
+ export { type Address as A, type BatchClaimParams as B, type CryptoPort as C, type DepositParams as D, type Envelope as E, type SafeDropErrorCode as F, type SecretHash as G, type Hex as H, type Id as I, type SocialIdentifier as J, type SocialProvider as K, type LeaderboardEntry as L, type MappedDepositResult as M, createSafeDrop as N, 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 HistoryReceiverParty as o, type HistoryStatus as p, type HistoryType as q, type LeaderboardPage as r, type MyLeaderboardEntry as s, type OnePopDrop as t, type RecipientChangeSignature as u, type RecipientSignature as v, type SafeDrop as w, type SafeDropConfig as x, type SafeDropDeps as y, SafeDropError as z };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as SafeDropChainPort, a as SafeDropApiPort, C as CryptoPort, D as DepositParams, b as DepositResult, B as BatchClaimParams, c as BatchClaimResult, d as ClaimSignerPort, W as WithdrawParams, e as WithdrawResult, R as RefundParams, f as RefundResult, A as Address, g as Secret } from './createSafeDrop-ClAk8kWV.js';
2
- export { h as BatchClaimSignature, i as DropInbox, j as DropSender, k as DropState, E as Envelope, H as Hex, l as HistoryEntry, m as HistoryPage, n as HistoryParty, o as HistoryType, I as Id, L as LeaderboardEntry, p as LeaderboardPage, M as MappedDepositResult, q as MyLeaderboardEntry, O as OAuthProof, r as OnePopDrop, P as PendingDrop, s as RecipientChangeSignature, t as RecipientSignature, u as RejectedDrops, v as SafeDrop, w as SafeDropConfig, x as SafeDropDeps, y as SafeDropError, z as SafeDropErrorCode, F as SecretHash, G as SocialIdentifier, J as SocialProvider, U as UnmappedDepositResult, X as XConnection, K as createSafeDrop } from './createSafeDrop-ClAk8kWV.js';
1
+ import { S as SafeDropChainPort, a as SafeDropApiPort, C as CryptoPort, D as DepositParams, b as DepositResult, B as BatchClaimParams, c as BatchClaimResult, d as ClaimSignerPort, W as WithdrawParams, e as WithdrawResult, R as RefundParams, f as RefundResult, A as Address, g as Secret } from './createSafeDrop-DtWLupoE.js';
2
+ export { h as BatchClaimSignature, i as DropInbox, j as DropSender, k as DropState, E as Envelope, H as Hex, l as HistoryEntry, m as HistoryPage, n as HistoryParty, o as HistoryReceiverParty, p as HistoryStatus, q as HistoryType, I as Id, L as LeaderboardEntry, r as LeaderboardPage, M as MappedDepositResult, s as MyLeaderboardEntry, O as OAuthProof, t as OnePopDrop, P as PendingDrop, u as RecipientChangeSignature, v as RecipientSignature, w as SafeDrop, x as SafeDropConfig, y as SafeDropDeps, z as SafeDropError, F as SafeDropErrorCode, G as SecretHash, J as SocialIdentifier, K as SocialProvider, U as UnmappedDepositResult, X as XConnection, N as createSafeDrop } from './createSafeDrop-DtWLupoE.js';
3
3
  export { X as XAuthPort, a as XTokenResult } from './XAuthPort-BNJePosj.js';
4
4
 
5
5
  /**
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{a as e,b as r,c as o,d as t,e as p,f as a,g as s,h as i,i as f,j as n,k as d}from"./chunk-RNPX7YGJ.js";export{i as BatchClaimUseCase,s as DepositUseCase,n as RefundUseCase,e as SafeDropError,f as WithdrawUseCase,a as buildComposeUrl,p as buildDmText,o as buildWithdrawLink,d as createSafeDrop,r as normalizeHandle,t as parseWithdrawLink};
1
+ import{a as r,b as e,c as o,d as t,e as p,f as a,g as s,h as i,i as f,j as n,k as m}from"./chunk-SX7PPVTJ.js";export{i as BatchClaimUseCase,s as DepositUseCase,n as RefundUseCase,r as SafeDropError,f as WithdrawUseCase,a as buildComposeUrl,p as buildDmText,o as buildWithdrawLink,m as createSafeDrop,e as normalizeHandle,t as parseWithdrawLink};
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { v as SafeDrop } from '../createSafeDrop-ClAk8kWV.js';
3
+ import { w as SafeDrop } from '../createSafeDrop-DtWLupoE.js';
4
4
 
5
5
  interface SafeDropProviderProps {
6
6
  client: SafeDrop;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexus-cross/pop",
3
- "version": "1.4.0-beta.4",
3
+ "version": "1.4.0-beta.6",
4
4
  "description": "pop — framework-agnostic core + React adapter.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -80,7 +80,7 @@
80
80
  "BearerAuth": []
81
81
  }
82
82
  ],
83
- "description": "Resolves the caller's handle from their active X connection (POST /x-connections) — no per-request X token. Senders with an active X connection carry handle/profile; others are address-only. amount/total_amount are wei decimal strings. mapped_recipient/pending_change_to mirror the on-chain id→recipient mapping (empty string = unmapped/none); when mapped, deposits must use depositMapped and POST /wallets responds 409. items[].drop_key is the bytes32 id for withdrawMapped/withdrawUnmapped calls. has_claimed_before is derived from the mapping row.",
83
+ "description": "Resolves the caller's handle from their active X connection (POST /x-connections) — no per-request X token. items[].sender profile fields are the snapshot recorded when the deposit was indexed, not the sponsor's current X mapping; empty means the sponsor had no active X connection at that time (address-only sender). amount/total_amount are wei decimal strings. mapped_recipient/pending_change_to mirror the on-chain id→recipient mapping (empty string = unmapped/none); when mapped, deposits must use depositMapped and POST /wallets responds 409. items[].drop_key is the bytes32 id for withdrawMapped/withdrawUnmapped calls. has_claimed_before is derived from the mapping row. items[].rejected marks drops the caller rejected — display-only, and excluded from count/total_amount. token is required; drop_key narrows to one drop. Both filters apply to items and to count/total_amount alike.",
84
84
  "produces": [
85
85
  "application/json"
86
86
  ],
@@ -91,8 +91,15 @@
91
91
  "parameters": [
92
92
  {
93
93
  "type": "string",
94
- "description": "ERC20 token address filter (0x hex)",
94
+ "description": "ERC20 token address filter (0x hex, required)",
95
95
  "name": "token",
96
+ "in": "query",
97
+ "required": true
98
+ },
99
+ {
100
+ "type": "string",
101
+ "description": "on-chain bytes32 drop id (0x + 64 hex) — single-drop lookup",
102
+ "name": "drop_key",
96
103
  "in": "query"
97
104
  }
98
105
  ],
@@ -213,7 +220,7 @@
213
220
  "BearerAuth": []
214
221
  }
215
222
  ],
216
- "description": "Marks the given pending drops as rejected for the caller's X account. Display filter only — batch-claim and on-chain flows are untouched, so this does NOT prevent claiming: a batch claim that does not exclude these keys (withdrawUnmappedBatchByKeys) will still claim them. Rejected drops disappear from GET /drops (list and totals) and appear in GET /drops/rejected. All-or-nothing: every id must be a pending drop addressed to the caller's connected X handle, otherwise the whole request fails with 40003 (ids cannot be enumerated). Re-rejecting an already-rejected drop is idempotent. Duplicate ids are deduped; count reports unique ids. Max 100 ids per request. No un-reject.",
223
+ "description": "Marks the given pending drops as rejected for the caller's X account. Display filter only — batch-claim and on-chain flows are untouched, so this does NOT prevent claiming: a batch claim that does not exclude these keys (withdrawUnmappedBatchByKeys) will still claim them. Rejected drops stay in GET /drops flagged with items[].rejected, but are excluded from count/total_amount. All-or-nothing: every id must be a pending drop addressed to the caller's connected X handle, otherwise the whole request fails with 40003 (ids cannot be enumerated). Re-rejecting an already-rejected drop is idempotent. Duplicate ids are deduped; count reports unique ids. Max 100 ids per request. No un-reject.",
217
224
  "consumes": [
218
225
  "application/json"
219
226
  ],
@@ -223,7 +230,7 @@
223
230
  "tags": [
224
231
  "drops"
225
232
  ],
226
- "summary": "Reject pending drops (hide from the claim inbox)",
233
+ "summary": "Reject pending drops (flagged in the claim inbox, excluded from its totals)",
227
234
  "parameters": [
228
235
  {
229
236
  "description": "drop row ids to reject",
@@ -275,49 +282,6 @@
275
282
  }
276
283
  }
277
284
  },
278
- "/drops/rejected": {
279
- "get": {
280
- "security": [
281
- {
282
- "BearerAuth": []
283
- }
284
- ],
285
- "description": "Lists drops the caller rejected that are still pending on-chain, newest first (max 100). Same item shape as GET /drops. A drop refunded on-chain after rejection drops out of this list (status leaves pending). Identity comes from the wallet's active X connection, like GET /drops.",
286
- "produces": [
287
- "application/json"
288
- ],
289
- "tags": [
290
- "drops"
291
- ],
292
- "summary": "List the caller's rejected drops",
293
- "responses": {
294
- "200": {
295
- "description": "OK",
296
- "schema": {
297
- "$ref": "#/definitions/types.RejectedDropsResp"
298
- }
299
- },
300
- "401": {
301
- "description": "20003 UNAUTHORIZED",
302
- "schema": {
303
- "$ref": "#/definitions/handler.errorBody"
304
- }
305
- },
306
- "404": {
307
- "description": "40002 X_CONNECTION_NOT_FOUND",
308
- "schema": {
309
- "$ref": "#/definitions/handler.errorBody"
310
- }
311
- },
312
- "500": {
313
- "description": "10002 INTERNAL",
314
- "schema": {
315
- "$ref": "#/definitions/handler.errorBody"
316
- }
317
- }
318
- }
319
- }
320
- },
321
285
  "/envelopes": {
322
286
  "get": {
323
287
  "description": "Public endpoint. Returns active envelopes within their display window, sorted. name resolves by locale with English fallback.",
@@ -461,7 +425,7 @@
461
425
  "BearerAuth": []
462
426
  }
463
427
  ],
464
- "description": "Drops-based activity history. type=sent returns drops sponsored by the authenticated wallet; type=received returns drops addressed to the wallet's active X handle or already claimed by the wallet (an active, non-expired X connection is required — 404 40002 otherwise). Both tabs include every status (pending/claimed/refunded), newest first. Each item carries both parties: sender (sponsor wallet + mapped X profile) and receiver (drop identifier handle + claiming wallet once withdrawn + mapped X profile); unmapped sides keep empty profile fields. amount is wei as a decimal string. The queried wallet always comes from the bearer token.",
428
+ "description": "Drops-based activity history. type=sent returns drops sponsored by the authenticated wallet; type=received returns every drop addressed to the wallet's active X handle, independent of which wallet claimed it (an active, non-expired X connection is required — 404 40002 otherwise). Both tabs include every status (pending/claimed/refunded), newest first. sender/receiver profiles are the point-in-time snapshot recorded when the deposit was indexed, not the current X mapping: changing an avatar or disconnecting X does not alter past items. Empty profile fields mean that side had no active X connection at that time. receiver.handle is the drop's identifier and receiver.address is the claiming wallet (null until claimed) for a recycled handle these two can refer to different accounts. amount is wei as a decimal string. The queried wallet always comes from the bearer token. rejected is true when the caller's X account rejected that drop (received only; always false on sent) — display-only, so rejected drops are still listed and counted, and status keeps its on-chain value. status narrows to one on-chain status; rejected narrows the received tab to the caller's own reject marks and is ignored on the sent tab. total reflects both filters.",
465
429
  "produces": [
466
430
  "application/json"
467
431
  ],
@@ -483,6 +447,18 @@
483
447
  "name": "token",
484
448
  "in": "query"
485
449
  },
450
+ {
451
+ "type": "string",
452
+ "description": "pending | claimed | refunded (default: all)",
453
+ "name": "status",
454
+ "in": "query"
455
+ },
456
+ {
457
+ "type": "string",
458
+ "description": "true | false — received tab only, ignored on sent",
459
+ "name": "rejected",
460
+ "in": "query"
461
+ },
486
462
  {
487
463
  "type": "integer",
488
464
  "description": "1-based page (default 1)",
@@ -1024,7 +1000,7 @@
1024
1000
  "BearerAuth": []
1025
1001
  }
1026
1002
  ],
1027
- "description": "Verifies the X OAuth token server-side (GET /2/users/me) and upserts the x_user_id -\u003e wallet mapping (latest connection wins). The wallet is always the SIWE-authenticated address. The response includes the account's stored reveal_you (default true on first connect, preserved on re-connect), and the leaderboard-visibility denylist is synced in the same transaction. The response also reports the scanner-mirrored on-chain id -\u003e recipient mapping for the connected handle (onchain_mapped / mapped_recipient; advisory, lag windows exist).",
1003
+ "description": "Verifies the X OAuth token server-side (GET /2/users/me) and upserts the x_user_id -\u003e wallet mapping (a re-connect refreshes the existing row). The wallet is always the SIWE-authenticated address. The response includes the account's stored reveal_you (default true on first connect, preserved on re-connect), and the leaderboard-visibility denylist is synced in the same transaction. The response also reports the scanner-mirrored on-chain id -\u003e recipient mapping for the connected handle (onchain_mapped / mapped_recipient; advisory, lag windows exist). An X account holds at most one active, non-expired wallet connection: connecting a different wallet while the previous one still qualifies returns 400 40004 X_ALREADY_CONNECTED — the previous wallet must call DELETE /x-connections, or the connection must age past the x-connection TTL.",
1028
1004
  "consumes": [
1029
1005
  "application/json"
1030
1006
  ],
@@ -1054,7 +1030,7 @@
1054
1030
  }
1055
1031
  },
1056
1032
  "400": {
1057
- "description": "10001 INVALID_PARAM",
1033
+ "description": "10001 INVALID_PARAM / 40004 X_ALREADY_CONNECTED",
1058
1034
  "schema": {
1059
1035
  "$ref": "#/definitions/handler.errorBody"
1060
1036
  }
@@ -1257,6 +1233,11 @@
1257
1233
  "type": "string",
1258
1234
  "example": "Happy birthday!"
1259
1235
  },
1236
+ "rejected": {
1237
+ "description": "Rejected reports whether the caller's X account rejected this\ndrop. Display-only, same meaning as HistoryItem.rejected:\nrejected drops stay in items but are excluded from count and\ntotal_amount, which report what is actually claimable.",
1238
+ "type": "boolean",
1239
+ "example": false
1240
+ },
1260
1241
  "sender": {
1261
1242
  "$ref": "#/definitions/types.DropSender"
1262
1243
  },
@@ -1307,7 +1288,7 @@
1307
1288
  "example": "Amy Ryoon"
1308
1289
  },
1309
1290
  "handle": {
1310
- "description": "Handle/DisplayName/ProfileImageURL are empty when the sponsor has\nno active X connection (address-only sender per the UI spec).",
1291
+ "description": "Handle/DisplayName/ProfileImageURL are the X snapshot recorded on\nthe drops row when the deposit was indexed, not the sponsor's\ncurrent X mapping. Empty when the sponsor had no active X\nconnection when the deposit was indexed (address-only sender per\nthe UI spec).",
1311
1292
  "type": "string",
1312
1293
  "example": "amyhryoon"
1313
1294
  },
@@ -1473,6 +1454,11 @@
1473
1454
  "receiver": {
1474
1455
  "$ref": "#/definitions/types.HistoryParty"
1475
1456
  },
1457
+ "rejected": {
1458
+ "description": "Rejected reports whether the caller's X account rejected this drop\n(received tab only; always false on sent). Display-only: rejected\nrows are still listed and still counted in total, and status keeps\nits on-chain meaning — reject never blocked the withdrawal.",
1459
+ "type": "boolean",
1460
+ "example": false
1461
+ },
1476
1462
  "resolved_at": {
1477
1463
  "type": "string"
1478
1464
  },
@@ -1710,21 +1696,6 @@
1710
1696
  }
1711
1697
  }
1712
1698
  },
1713
- "types.RejectedDropsResp": {
1714
- "type": "object",
1715
- "properties": {
1716
- "count": {
1717
- "type": "integer",
1718
- "example": 3
1719
- },
1720
- "items": {
1721
- "type": "array",
1722
- "items": {
1723
- "$ref": "#/definitions/types.DropItem"
1724
- }
1725
- }
1726
- }
1727
- },
1728
1699
  "types.RetrievePrivateKeyReq": {
1729
1700
  "type": "object",
1730
1701
  "required": [
@@ -1 +0,0 @@
1
- var i=class extends Error{constructor(e,r,n){super(r),this.name="SafeDropError",this.code=e,this.details=n}};function g(a){return a.trim().replace(/^@/,"").toLowerCase()}function w(a){let e=a.baseUrl.replace(/\/$/,""),r=e.includes("?")?"&":"?",n=a.claimAddress?`&claim=${encodeURIComponent(a.claimAddress)}`:"",s=`${e}${r}sender=${encodeURIComponent(a.sender)}${n}`;return a.secret?`${s}#${encodeURIComponent(a.secret)}`:s}function b(a){let e=a.indexOf("#"),r=e===-1?a:a.slice(0,e),n=e===-1?"":a.slice(e+1),s=r.indexOf("?"),d=s===-1?"":r.slice(s+1);return{sender:A(d,"sender"),secret:n?decodeURIComponent(n):null}}function M(a){return`\u{1F381} You've received a one-pop drop! Claim your tokens here: ${a}`}function H(a,e){let r=[`text=${encodeURIComponent(a)}`];return e&&r.push(`recipient_id=${encodeURIComponent(e)}`),`https://x.com/messages/compose?${r.join("&")}`}function A(a,e){if(!a)return null;for(let r of a.split("&")){if(!r)continue;let n=r.indexOf("=");if(decodeURIComponent(n===-1?r:r.slice(0,n))===e)return decodeURIComponent(n===-1?"":r.slice(n+1))}return null}var y=class{constructor(e,r,n,s){this.chain=e;this.api=r;this.crypto=n;this.claimBaseUrl=s}async execute(e){if(!e.sender)throw new i("MISSING_SENDER","sender address is required");if(!e.recipient?.handle)throw new i("MISSING_RECIPIENT","recipient social handle is required");if(!e.token)throw new i("INVALID_TOKEN","token address is required (ERC20 only)");if(e.amount<=0n)throw new i("INVALID_AMOUNT","amount must be a positive BigInt");if(e.message&&[...e.message].length>140)throw new i("INVALID_PARAM","message must be <= 140 runes");let r=g(e.recipient.handle);if(!r)throw new i("MISSING_RECIPIENT","recipient handle normalizes to empty");let n=await this.api.createClaimWallet({sender:e.sender,recipient:{...e.recipient,handle:r}}),s=n.id,d=async m=>{if(this.api.recordDropMetadata)try{await this.api.recordDropMetadata({txHash:m,message:e.message,envelopeId:e.envelopeId})}catch(u){if(u instanceof i&&u.details?.codeName==="ENVELOPE_NOT_FOUND"&&e.envelopeId)try{await this.api.recordDropMetadata({txHash:m,message:e.message})}catch{}}};if(n.isMapped){let{txHash:m}=await this.chain.depositMapped({token:e.token,amount:e.amount,id:s,onSubmitted:d});return{isMapped:!0,depositTxHash:m}}let o=e.secret??this.crypto.randomSecret();if(!o)throw new i("MISSING_SECRET","secret is empty");let t=this.crypto.keccak256(o),p={claimAddress:n.claimAddress,token:e.token,amount:e.amount,id:s,secretHash:t,onSubmitted:d},{txHash:h}=await this.chain.depositWithPermit(p);return{isMapped:!1,claimAddress:n.claimAddress,secretHash:t,withdrawLink:w({baseUrl:this.claimBaseUrl,sender:e.sender,claimAddress:n.claimAddress,secret:o}),depositTxHash:h}}};var N=BigInt(1800),x=30,f=class{constructor(e,r,n,s=()=>Date.now()){this.chain=e;this.api=r;this.crypto=n;this.now=s}async execute(e){let r=g(e.id);if(!r)throw new i("MISSING_RECIPIENT","batchClaim requires an id");if(!e.claimAddress)throw new i("MISSING_CLAIM_ADDRESS","claim address is required");if(!e.sponsor)throw new i("MISSING_SENDER","sponsor address is required");if(!e.claimKey)throw new i("MISSING_CLAIM_KEY","claim key is required");if(!e.secret)throw new i("MISSING_SECRET","secret is required");if(!this.api.requestBatchClaimSignature)throw new i("API_ERROR","requestBatchClaimSignature is not implemented");if(!this.chain.getValidatorNonce||!this.chain.getValidatorClaimDigest||!this.chain.getValidator)throw new i("CHAIN_ERROR","validator reads are not implemented");let n=await this.chain.getDropKeyByClaimAddress(e.claimAddress,e.sponsor);if(!n)throw new i("DROP_NOT_FOUND","anchor drop not found");let s=await this.chain.getDropByKey(n);if(!s||s.id!==r)throw new i("DROP_NOT_FOUND","anchor drop id does not match");let d=await this.chain.getPendingDropsById({id:r});if(!d.length)throw new i("DROP_NOT_FOUND",`No pending drops for ${r}`);let o=e.maxCount??x;if(!Number.isSafeInteger(o)||o<=0)throw new i("INVALID_PARAM","maxCount must be a positive safe integer");let t=e.deadline??BigInt(Math.floor(this.now()/1e3))+(e.deadlineTtlSeconds??N),p=[],h="",m=BigInt(0);for(;d.length;){let u=await this.chain.getValidatorNonce({id:r}),l=await this.api.requestBatchClaimSignature({id:r,oauth:e.oauth,nonce:u,deadline:t});if(e.recipient&&e.recipient.toLowerCase()!==l.recipient.toLowerCase())throw new i("SIGN_FAILED","validator signature is bound to a different recipient");if(h&&h.toLowerCase()!==l.recipient.toLowerCase())throw new i("SIGN_FAILED","validator recipient changed between batches");h=l.recipient,p.length||(m=l.nonce);let R=await this.chain.getValidatorClaimDigest({recipient:h,id:r,nonce:l.nonce,deadline:l.deadline});await this.assertSignedByValidator(R,l.signature);let I=d.length,C=await this.chain.withdrawUnmappedBatchByKeys({claimKey:e.claimKey,recipient:h,id:r,anchorDropKey:n,secret:e.secret,nonce:l.nonce,deadline:l.deadline,dropKeys:d.slice(0,o).map(S=>S.dropKey).filter(S=>S.toLowerCase()!==n.toLowerCase()),validatorSignature:l.signature});if(p.push(C),d=await this.chain.getPendingDropsById({id:r}),d.length>=I)throw new i("CHAIN_ERROR","batch claim made no progress",{id:r,txHash:C})}return{txHashes:p,recipient:h,id:r,nonce:m,deadline:t}}async assertSignedByValidator(e,r){if(!this.crypto.recoverAddress||!this.chain.getValidator)return;let[n,s]=await Promise.all([this.crypto.recoverAddress({digest:e,signature:r}),this.chain.getValidator()]);if(n.toLowerCase()!==s.toLowerCase())throw new i("SIGN_FAILED","batch-claim signature does not recover to validator")}};var D=class{constructor(e,r){this.chain=e;this.signer=r}async execute(e){if(!e.recipient)throw new i("MISSING_RECIPIENT","recipient address is required");if(!e.claimAddress)throw new i("MISSING_CLAIM_ADDRESS","claim address is required");if(!e.secret)throw new i("MISSING_SECRET","secret is required");if(!e.claimKey)throw new i("MISSING_CLAIM_KEY","claim key is required");if(!e.sponsor)throw new i("MISSING_SENDER","sponsor address is required");let r=await this.chain.getDropKeyByClaimAddress(e.claimAddress,e.sponsor);if(!r)throw new i("DROP_NOT_FOUND",`No drop for claim address ${e.claimAddress}`);let n=await this.chain.getDropByKey(r);if(!n)throw new i("DROP_NOT_FOUND",`No drop for key ${r}`);let s=await this.chain.getClaimDigest({recipient:e.recipient,id:n.id,dropKey:r}),d=await this.signer.signDigest({claimKey:e.claimKey,digest:s});return{txHash:await this.chain.withdrawUnmapped({claimKey:e.claimKey,recipient:e.recipient,id:n.id,dropKey:r,signature:d,secret:e.secret})}}};var P=class{constructor(e){this.chain=e}async execute(e){if(!e.claimAddress)throw new i("MISSING_CLAIM_ADDRESS","claim address is required");if(!e.sponsor)throw new i("MISSING_SENDER","sponsor address is required");let r=await this.chain.getDropKeyByClaimAddress(e.claimAddress,e.sponsor);if(!r)throw new i("DROP_NOT_FOUND",`No drop for claim address ${e.claimAddress}`);return{txHash:await this.chain.refundByKey({dropKey:r})}}};function c(a,e){if(!a)throw new i("API_ERROR",`SafeDropApiPort.${e} is not implemented by the injected api adapter`);return a}function z(a,e){let r=new y(e.chain,e.api,e.crypto,a.claimBaseUrl),n=new D(e.chain,e.signer),s=new P(e.chain),d=new f(e.chain,e.api,e.crypto),{api:o}=e;return{config:a,deposit:t=>r.execute(t),retrieveClaimKey:t=>o.retrieveClaimKey(t),withdraw:t=>n.execute(t),refund:t=>s.execute(t),getDrop:(t,p)=>e.chain.getDrop(t,p),getDropByKey:t=>e.chain.getDropByKey(t),getDropKeyByClaimAddress:(t,p)=>e.chain.getDropKeyByClaimAddress(t,p),getClaimedRecipient:t=>e.chain.getClaimedRecipient({id:t}),getPendingDropsById:t=>e.chain.getPendingDropsById({id:t}),getPendingDropsByRecipient:t=>e.chain.getPendingDropsByRecipient({recipient:t}),getPendingDropsBySponsor:t=>e.chain.getPendingDropsBySponsor({sponsor:t}),withdrawUnmapped:t=>e.chain.withdrawUnmapped(t),withdrawMapped:t=>e.chain.withdrawMapped(t),batchWithdrawMapped:t=>e.chain.batchWithdrawMapped({count:t}),batchWithdrawMappedByKeys:t=>e.chain.batchWithdrawMappedByKeys({dropKeys:t}),refundByKey:t=>e.chain.refundByKey({dropKey:t}),getChangeNonce:t=>e.chain.getChangeNonce({id:t}),getPendingRecipientChange:t=>e.chain.getPendingRecipientChange({id:t}),requestRecipientChange:(t,p)=>e.chain.requestRecipientChange({id:t,newRecipient:p}),completeRecipientChange:t=>e.chain.completeRecipientChange(t),cancelRecipientChange:t=>e.chain.cancelRecipientChange({id:t}),resetRecipient:t=>e.chain.resetRecipient(t),listDrops:t=>c(o.listDrops,"listDrops").call(o,t),rejectDrops:t=>c(o.rejectDrops,"rejectDrops").call(o,{dropIds:t}),listRejectedDrops:()=>c(o.listRejectedDrops,"listRejectedDrops").call(o),listEnvelopes:t=>c(o.listEnvelopes,"listEnvelopes").call(o,t),getLeaderboard:t=>c(o.getLeaderboard,"getLeaderboard").call(o,t),getMyLeaderboardEntry:t=>c(o.getMyLeaderboardEntry,"getMyLeaderboardEntry").call(o,t),listHistories:t=>c(o.listHistories,"listHistories").call(o,t),getXConnection:()=>c(o.getXConnection,"getXConnection").call(o),connectX:t=>c(o.connectX,"connectX").call(o,t),disconnectX:()=>c(o.disconnectX,"disconnectX").call(o),submitFeedback:t=>c(o.submitFeedback,"submitFeedback").call(o,t),setRevealYou:t=>c(o.setRevealYou,"setRevealYou").call(o,{revealYou:t}),requestRecipientChangeSignature:t=>c(o.requestRecipientChangeSignature,"requestRecipientChangeSignature").call(o,t),requestRecipientResetSignature:t=>c(o.requestRecipientResetSignature,"requestRecipientResetSignature").call(o,t),batchClaim:t=>d.execute(t),requestBatchClaimSignature:t=>c(o.requestBatchClaimSignature,"requestBatchClaimSignature").call(o,t)}}export{i as a,g as b,w as c,b as d,M as e,H as f,y as g,f as h,D as i,P as j,z as k};