@waterx/sdk 2.1.0 → 2.3.1-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/README.md +75 -169
  2. package/dist/src/client.d.ts +52 -2
  3. package/dist/src/client.js +76 -6
  4. package/dist/src/config.d.ts +57 -3
  5. package/dist/src/config.js +10 -4
  6. package/dist/src/constants.d.ts +6 -0
  7. package/dist/src/constants.js +6 -0
  8. package/dist/src/core/waterx-account.d.ts +31 -0
  9. package/dist/src/core/waterx-account.js +26 -0
  10. package/dist/src/fetch.d.ts +110 -0
  11. package/dist/src/fetch.js +149 -4
  12. package/dist/src/generated/bucket_v2_framework/account.d.ts +5 -5
  13. package/dist/src/generated/bucket_v2_framework/double.d.ts +77 -77
  14. package/dist/src/generated/bucket_v2_framework/float.d.ts +73 -73
  15. package/dist/src/generated/bucket_v2_framework/liability.d.ts +33 -33
  16. package/dist/src/generated/bucket_v2_framework/linked_table.d.ts +5 -5
  17. package/dist/src/generated/bucket_v2_framework/linked_table.js +2 -2
  18. package/dist/src/generated/bucket_v2_framework/sheet.d.ts +57 -57
  19. package/dist/src/generated/bucket_v2_framework/sheet.js +5 -11
  20. package/dist/src/generated/native_custody/custody_vault.d.ts +46 -32
  21. package/dist/src/generated/native_custody/custody_vault.js +19 -10
  22. package/dist/src/generated/native_custody/deps/bucket_v2_framework/sheet.js +1 -3
  23. package/dist/src/generated/native_custody/events.js +1 -2
  24. package/dist/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.d.ts +7 -7
  25. package/dist/src/generated/pyth_sponsor_rule/pyth_sponsor_rule.js +1 -2
  26. package/dist/src/generated/utils/index.d.ts +7 -7
  27. package/dist/src/generated/utils/index.js +9 -6
  28. package/dist/src/generated/waterx_account/account.d.ts +124 -71
  29. package/dist/src/generated/waterx_account/account.js +64 -29
  30. package/dist/src/generated/waterx_account/deps/bucket_v2_framework/sheet.js +1 -3
  31. package/dist/src/generated/waterx_account/direct_rule.d.ts +5 -5
  32. package/dist/src/generated/waterx_account/events.d.ts +10 -0
  33. package/dist/src/generated/waterx_account/events.js +31 -50
  34. package/dist/src/generated/waterx_constant_rule/constant_rule.d.ts +68 -0
  35. package/dist/src/generated/waterx_constant_rule/constant_rule.js +59 -0
  36. package/dist/src/generated/waterx_constant_rule/deps/bucket_v2_framework/float.d.ts +8 -0
  37. package/dist/src/generated/waterx_constant_rule/deps/bucket_v2_framework/float.js +10 -0
  38. package/dist/src/generated/waterx_constant_rule/deps/sui/vec_map.d.ts +36 -0
  39. package/dist/src/generated/waterx_constant_rule/deps/sui/vec_map.js +27 -0
  40. package/dist/src/generated/waterx_credit/credit_registry.d.ts +9 -9
  41. package/dist/src/generated/waterx_credit/credit_registry.js +1 -2
  42. package/dist/src/generated/waterx_credit/limited_supply.d.ts +17 -17
  43. package/dist/src/generated/waterx_oracle/aggregator.js +1 -2
  44. package/dist/src/generated/waterx_oracle/collector.d.ts +17 -17
  45. package/dist/src/generated/waterx_oracle/collector.js +1 -1
  46. package/dist/src/generated/waterx_oracle/oracle.d.ts +5 -5
  47. package/dist/src/generated/waterx_perp/account_data.d.ts +5 -5
  48. package/dist/src/generated/waterx_perp/account_data.js +1 -2
  49. package/dist/src/generated/waterx_perp/deps/bucket_v2_framework/sheet.js +1 -3
  50. package/dist/src/generated/waterx_perp/events.d.ts +181 -181
  51. package/dist/src/generated/waterx_perp/events.js +87 -173
  52. package/dist/src/generated/waterx_perp/global_config.d.ts +3 -3
  53. package/dist/src/generated/waterx_perp/global_config.js +6 -12
  54. package/dist/src/generated/waterx_perp/keyed_big_vector.d.ts +9 -9
  55. package/dist/src/generated/waterx_perp/keyed_big_vector.js +1 -2
  56. package/dist/src/generated/waterx_perp/lp_pool.d.ts +115 -115
  57. package/dist/src/generated/waterx_perp/lp_pool.js +11 -22
  58. package/dist/src/generated/waterx_perp/market_config.d.ts +61 -43
  59. package/dist/src/generated/waterx_perp/market_config.js +29 -22
  60. package/dist/src/generated/waterx_perp/math.d.ts +7 -7
  61. package/dist/src/generated/waterx_perp/order_book.d.ts +47 -47
  62. package/dist/src/generated/waterx_perp/position.d.ts +99 -99
  63. package/dist/src/generated/waterx_perp/position.js +6 -12
  64. package/dist/src/generated/waterx_perp/request.d.ts +67 -67
  65. package/dist/src/generated/waterx_perp/request.js +2 -3
  66. package/dist/src/generated/waterx_perp/response.d.ts +35 -35
  67. package/dist/src/generated/waterx_perp/response.js +1 -2
  68. package/dist/src/generated/waterx_perp/trading.d.ts +303 -179
  69. package/dist/src/generated/waterx_perp/trading.js +99 -14
  70. package/dist/src/generated/waterx_perp_view/view.js +5 -10
  71. package/dist/src/generated/waterx_pyth_rule/pyth_rule.d.ts +5 -5
  72. package/dist/src/generated/waterx_pyth_rule/pyth_rule.js +1 -2
  73. package/dist/src/generated/waterx_referral/referral_table.d.ts +5 -5
  74. package/dist/src/generated/waterx_referral/referral_table.js +1 -2
  75. package/dist/src/generated/waterx_staking/waterx_staking.d.ts +19 -19
  76. package/dist/src/generated/waterx_staking/waterx_staking.js +10 -20
  77. package/dist/src/generated/waterx_supra_rule/deps/sui/vec_map.d.ts +36 -0
  78. package/dist/src/generated/waterx_supra_rule/deps/sui/vec_map.js +27 -0
  79. package/dist/src/generated/waterx_supra_rule/supra_rule.d.ts +158 -0
  80. package/dist/src/generated/waterx_supra_rule/supra_rule.js +148 -0
  81. package/dist/src/generated/withdrawal_queue/deps/bucket_v2_framework/float.d.ts +8 -0
  82. package/dist/src/generated/withdrawal_queue/deps/bucket_v2_framework/float.js +10 -0
  83. package/dist/src/generated/withdrawal_queue/deps/sui/vec_map.d.ts +36 -0
  84. package/dist/src/generated/withdrawal_queue/deps/sui/vec_map.js +27 -0
  85. package/dist/src/generated/withdrawal_queue/withdrawal_queue.d.ts +444 -4
  86. package/dist/src/generated/withdrawal_queue/withdrawal_queue.js +417 -4
  87. package/dist/src/generated/wormhole_bridge/wormhole_bridge.d.ts +214 -74
  88. package/dist/src/generated/wormhole_bridge/wormhole_bridge.js +158 -29
  89. package/dist/src/index.d.ts +4 -3
  90. package/dist/src/index.js +3 -2
  91. package/dist/src/prediction/account.d.ts +96 -0
  92. package/dist/src/prediction/account.js +230 -0
  93. package/dist/src/prediction/admin.d.ts +47 -0
  94. package/dist/src/prediction/admin.js +105 -0
  95. package/dist/src/prediction/bcs.d.ts +22 -0
  96. package/dist/src/prediction/bcs.js +240 -0
  97. package/dist/src/prediction/client.d.ts +75 -0
  98. package/dist/src/prediction/client.js +164 -0
  99. package/dist/src/prediction/config.d.ts +60 -0
  100. package/dist/src/prediction/config.js +75 -0
  101. package/dist/src/prediction/constants.d.ts +44 -0
  102. package/dist/src/prediction/constants.js +46 -0
  103. package/dist/src/prediction/fetch.d.ts +82 -0
  104. package/dist/src/prediction/fetch.js +270 -0
  105. package/dist/src/prediction/generated/bucket_v2_framework/account.d.ts +100 -0
  106. package/dist/src/prediction/generated/bucket_v2_framework/account.js +129 -0
  107. package/dist/src/prediction/generated/bucket_v2_framework/deps/std/type_name.d.ts +6 -0
  108. package/dist/src/prediction/generated/bucket_v2_framework/deps/std/type_name.js +19 -0
  109. package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/balance.d.ts +10 -0
  110. package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/balance.js +14 -0
  111. package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/vec_map.d.ts +36 -0
  112. package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/vec_map.js +27 -0
  113. package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/vec_set.d.ts +16 -0
  114. package/dist/src/prediction/generated/bucket_v2_framework/deps/sui/vec_set.js +19 -0
  115. package/dist/src/prediction/generated/bucket_v2_framework/double.d.ts +382 -0
  116. package/dist/src/prediction/generated/bucket_v2_framework/double.js +466 -0
  117. package/dist/src/prediction/generated/bucket_v2_framework/float.d.ts +362 -0
  118. package/dist/src/prediction/generated/bucket_v2_framework/float.js +440 -0
  119. package/dist/src/prediction/generated/bucket_v2_framework/liability.d.ts +193 -0
  120. package/dist/src/prediction/generated/bucket_v2_framework/liability.js +205 -0
  121. package/dist/src/prediction/generated/bucket_v2_framework/linked_table.d.ts +384 -0
  122. package/dist/src/prediction/generated/bucket_v2_framework/linked_table.js +382 -0
  123. package/dist/src/prediction/generated/bucket_v2_framework/sheet.d.ts +344 -0
  124. package/dist/src/prediction/generated/bucket_v2_framework/sheet.js +338 -0
  125. package/dist/src/prediction/generated/utils/index.d.ts +30 -0
  126. package/dist/src/prediction/generated/utils/index.js +160 -0
  127. package/dist/src/prediction/generated/waterx_account/account.d.ts +1589 -0
  128. package/dist/src/prediction/generated/waterx_account/account.js +1758 -0
  129. package/dist/src/prediction/generated/waterx_account/deps/bucket_v2_framework/liability.d.ts +7 -0
  130. package/dist/src/prediction/generated/waterx_account/deps/bucket_v2_framework/liability.js +13 -0
  131. package/dist/src/prediction/generated/waterx_account/deps/bucket_v2_framework/sheet.d.ts +7 -0
  132. package/dist/src/prediction/generated/waterx_account/deps/bucket_v2_framework/sheet.js +16 -0
  133. package/dist/src/prediction/generated/waterx_account/deps/std/type_name.d.ts +6 -0
  134. package/dist/src/prediction/generated/waterx_account/deps/std/type_name.js +19 -0
  135. package/dist/src/prediction/generated/waterx_account/deps/sui/balance.d.ts +10 -0
  136. package/dist/src/prediction/generated/waterx_account/deps/sui/balance.js +14 -0
  137. package/dist/src/prediction/generated/waterx_account/deps/sui/object_table.d.ts +12 -0
  138. package/dist/src/prediction/generated/waterx_account/deps/sui/object_table.js +19 -0
  139. package/dist/src/prediction/generated/waterx_account/deps/sui/table.d.ts +24 -0
  140. package/dist/src/prediction/generated/waterx_account/deps/sui/table.js +31 -0
  141. package/dist/src/prediction/generated/waterx_account/deps/sui/vec_map.d.ts +36 -0
  142. package/dist/src/prediction/generated/waterx_account/deps/sui/vec_map.js +27 -0
  143. package/dist/src/prediction/generated/waterx_account/deps/sui/vec_set.d.ts +16 -0
  144. package/dist/src/prediction/generated/waterx_account/deps/sui/vec_set.js +19 -0
  145. package/dist/src/prediction/generated/waterx_account/direct_rule.d.ts +75 -0
  146. package/dist/src/prediction/generated/waterx_account/direct_rule.js +78 -0
  147. package/dist/src/prediction/generated/waterx_account/events.d.ts +33 -0
  148. package/dist/src/prediction/generated/waterx_account/events.js +137 -0
  149. package/dist/src/prediction/generated/waterx_account/version.d.ts +10 -0
  150. package/dist/src/prediction/generated/waterx_account/version.js +8 -0
  151. package/dist/src/prediction/generated/waterx_prediction/account_data.d.ts +327 -0
  152. package/dist/src/prediction/generated/waterx_prediction/account_data.js +405 -0
  153. package/dist/src/prediction/generated/waterx_prediction/admin.d.ts +5 -0
  154. package/dist/src/prediction/generated/waterx_prediction/admin.js +9 -0
  155. package/dist/src/prediction/generated/waterx_prediction/bet_sharing.d.ts +60 -0
  156. package/dist/src/prediction/generated/waterx_prediction/bet_sharing.js +83 -0
  157. package/dist/src/prediction/generated/waterx_prediction/deps/bucket_v2_framework/linked_table.d.ts +8 -0
  158. package/dist/src/prediction/generated/waterx_prediction/deps/bucket_v2_framework/linked_table.js +18 -0
  159. package/dist/src/prediction/generated/waterx_prediction/deps/sui/balance.d.ts +10 -0
  160. package/dist/src/prediction/generated/waterx_prediction/deps/sui/balance.js +14 -0
  161. package/dist/src/prediction/generated/waterx_prediction/deps/sui/table.d.ts +24 -0
  162. package/dist/src/prediction/generated/waterx_prediction/deps/sui/table.js +31 -0
  163. package/dist/src/prediction/generated/waterx_prediction/deps/sui/vec_set.d.ts +16 -0
  164. package/dist/src/prediction/generated/waterx_prediction/deps/sui/vec_set.js +19 -0
  165. package/dist/src/prediction/generated/waterx_prediction/events.d.ts +22 -0
  166. package/dist/src/prediction/generated/waterx_prediction/events.js +179 -0
  167. package/dist/src/prediction/generated/waterx_prediction/global_config.d.ts +116 -0
  168. package/dist/src/prediction/generated/waterx_prediction/global_config.js +141 -0
  169. package/dist/src/prediction/generated/waterx_prediction/order.d.ts +200 -0
  170. package/dist/src/prediction/generated/waterx_prediction/order.js +284 -0
  171. package/dist/src/prediction/generated/waterx_prediction/outcome.d.ts +58 -0
  172. package/dist/src/prediction/generated/waterx_prediction/outcome.js +73 -0
  173. package/dist/src/prediction/generated/waterx_prediction/position.d.ts +160 -0
  174. package/dist/src/prediction/generated/waterx_prediction/position.js +214 -0
  175. package/dist/src/prediction/generated/waterx_prediction/version.d.ts +10 -0
  176. package/dist/src/prediction/generated/waterx_prediction/version.js +8 -0
  177. package/dist/src/prediction/generated/waterx_prediction/view.d.ts +353 -0
  178. package/dist/src/prediction/generated/waterx_prediction/view.js +432 -0
  179. package/dist/src/prediction/generated/waterx_prediction/waterx_prediction.d.ts +1698 -0
  180. package/dist/src/prediction/generated/waterx_prediction/waterx_prediction.js +1733 -0
  181. package/dist/src/prediction/gift-link.d.ts +6 -0
  182. package/dist/src/prediction/gift-link.js +5 -0
  183. package/dist/src/prediction/gift.d.ts +223 -0
  184. package/dist/src/prediction/gift.js +451 -0
  185. package/dist/src/prediction/index.d.ts +29 -0
  186. package/dist/src/prediction/index.js +21 -0
  187. package/dist/src/prediction/prediction.d.ts +104 -0
  188. package/dist/src/prediction/prediction.js +317 -0
  189. package/dist/src/prediction/tx-builders.d.ts +44 -0
  190. package/dist/src/prediction/tx-builders.js +52 -0
  191. package/dist/src/prediction/types.d.ts +93 -0
  192. package/dist/src/prediction/types.js +1 -0
  193. package/dist/src/prediction/user/account.d.ts +2 -0
  194. package/dist/src/prediction/user/account.js +1 -0
  195. package/dist/src/prediction/user/admin.d.ts +6 -0
  196. package/dist/src/prediction/user/admin.js +3 -0
  197. package/dist/src/prediction/user/gift.d.ts +2 -0
  198. package/dist/src/prediction/user/gift.js +1 -0
  199. package/dist/src/prediction/user/index.d.ts +5 -0
  200. package/dist/src/prediction/user/index.js +3 -0
  201. package/dist/src/prediction/user/keeper.d.ts +2 -0
  202. package/dist/src/prediction/user/keeper.js +1 -0
  203. package/dist/src/prediction/user/order.d.ts +2 -0
  204. package/dist/src/prediction/user/order.js +1 -0
  205. package/dist/src/prediction/user/position.d.ts +2 -0
  206. package/dist/src/prediction/user/position.js +1 -0
  207. package/dist/src/prediction/utils/bcs.d.ts +1 -0
  208. package/dist/src/prediction/utils/bcs.js +1 -0
  209. package/dist/src/prediction/utils/index.d.ts +1 -0
  210. package/dist/src/prediction/utils/index.js +1 -0
  211. package/dist/src/prediction/utils.d.ts +30 -0
  212. package/dist/src/prediction/utils.js +177 -0
  213. package/dist/src/sdk.d.ts +18 -0
  214. package/dist/src/sdk.js +17 -0
  215. package/dist/src/tx-builders.d.ts +54 -0
  216. package/dist/src/tx-builders.js +141 -0
  217. package/dist/src/unified-client.d.ts +407 -0
  218. package/dist/src/unified-client.js +123 -0
  219. package/dist/src/user/account.d.ts +27 -0
  220. package/dist/src/user/account.js +34 -8
  221. package/dist/src/user/credit.d.ts +8 -14
  222. package/dist/src/user/credit.js +9 -23
  223. package/dist/src/user/custody.d.ts +4 -18
  224. package/dist/src/user/custody.js +14 -25
  225. package/dist/src/utils/consolidate-balance.d.ts +37 -0
  226. package/dist/src/utils/consolidate-balance.js +89 -0
  227. package/dist/src/utils/math.d.ts +86 -0
  228. package/dist/src/utils/math.js +100 -0
  229. package/dist/src/utils/pyth.d.ts +35 -3
  230. package/dist/src/utils/pyth.js +145 -14
  231. package/package.json +129 -34
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Browser-safe re-exports of gift URL / KDF crypto helpers (no PredictClient / RPC).
3
+ * Full gift runtime (PTB builders + simulate reads) lives in `./gift.ts`.
4
+ */
5
+ export { base64UrlNoPadDecode, base64UrlNoPadEncode, buildGiftClaimMessage, deriveGiftKeypair, encodeGiftUrl, generateGiftSeed, parseGiftUrl, signGiftClaim, } from "./gift.ts";
6
+ export type { GiftUrlParts } from "./gift.ts";
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Browser-safe re-exports of gift URL / KDF crypto helpers (no PredictClient / RPC).
3
+ * Full gift runtime (PTB builders + simulate reads) lives in `./gift.ts`.
4
+ */
5
+ export { base64UrlNoPadDecode, base64UrlNoPadEncode, buildGiftClaimMessage, deriveGiftKeypair, encodeGiftUrl, generateGiftSeed, parseGiftUrl, signGiftClaim, } from "./gift.js";
@@ -0,0 +1,223 @@
1
+ /**
2
+ * waterx_prediction_gift / claimable_link bindings.
3
+ *
4
+ * Three responsibilities:
5
+ *
6
+ * 1. **KDF + signed-message format** — turn a 16-byte URL seed into an
7
+ * Ed25519 keypair (sha256 over a package-prefixed domain) and build
8
+ * the exact 92-byte payload `claim_share` verifies on chain.
9
+ * Every byte here must match `claimable_link.move` — one wrong byte
10
+ * and outstanding URLs break.
11
+ *
12
+ * 2. **URL helpers + offline gift-address derivation** — base64url(no-pad)
13
+ * encode/decode of the seed (URL fragment), and `deriveGiftAddress`
14
+ * which mirrors `derived_object::derive_address` locally so a
15
+ * receiver can compute `gift_id` from the seed without any RPC.
16
+ *
17
+ * 3. **PTB builders + simulate reads** — `createGift` / `claimShare` /
18
+ * `deleteGift` matching the on-chain entrypoints, plus single-RPC
19
+ * `simulateTransaction`-based read helpers for the view fns.
20
+ */
21
+ import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
22
+ import { Transaction } from "@mysten/sui/transactions";
23
+ import type { PredictClient } from "./client.ts";
24
+ import type { AccountIdentityParams, IdArgument, Selection } from "./types.ts";
25
+ export interface GiftBaseParams {
26
+ /** `waterx_prediction_gift` package id. Defaults to `client.waterxPredictionGiftPackageId()`. */
27
+ giftPackageId?: string;
28
+ /** `ClaimableLinkConfig` object id. Defaults to `client.claimableLinkConfigId()`. */
29
+ claimableLinkConfig?: string;
30
+ /** Collateral / settlement coin type for the position's `Gift<T>`. Defaults to `client.settlementCoinType()`. */
31
+ settlementCoinType?: string;
32
+ }
33
+ export interface GiftReferralParams {
34
+ /** `waterx_referral` package id. Defaults to `client.waterxReferralPackageId()`. */
35
+ referralPackageId?: string;
36
+ /** `ReferralTable` object id. Defaults to `client.referralTableId()`. */
37
+ referralTable?: string;
38
+ }
39
+ export declare function base64UrlNoPadEncode(bytes: Uint8Array): string;
40
+ export declare function base64UrlNoPadDecode(value: string): Uint8Array;
41
+ /** CSPRNG-generated 16-byte URL seed. Uses `globalThis.crypto.getRandomValues`. */
42
+ export declare function generateGiftSeed(): Uint8Array;
43
+ export interface GiftUrlParts {
44
+ /** Optional URL base (`https://waterx.io`). Empty → fragment-only path `/g/#<seed>`. */
45
+ host?: string;
46
+ /** Path prefix before `#<seed>`. Defaults to `/g/`. */
47
+ path?: string;
48
+ }
49
+ /** Build the share URL: `<host><path>#<base64urlnopad(seed)>`. */
50
+ export declare function encodeGiftUrl(seed: Uint8Array, parts?: GiftUrlParts): string;
51
+ /** Parse a share URL or fragment-only string back into the raw seed bytes. */
52
+ export declare function parseGiftUrl(url: string): {
53
+ seed: Uint8Array;
54
+ };
55
+ /**
56
+ * Off-chain KDF: `sha256(KDF_DOMAIN || seed)` → 32-byte Ed25519 secret.
57
+ * Bytes MUST match across SDK versions and downstream integrations or
58
+ * every outstanding URL breaks.
59
+ */
60
+ export declare function deriveGiftKeypair(seed: Uint8Array): Ed25519Keypair;
61
+ /**
62
+ * Reproduce the bytes `claim_share` verifies:
63
+ * `DOMAIN_CLAIM || bcs(gift_id) || bcs(sender)` = 28 + 32 + 32 = 92 bytes.
64
+ */
65
+ export declare function buildGiftClaimMessage(giftId: string, sender: string): Uint8Array;
66
+ /**
67
+ * Raw Ed25519 over the claim payload — NOT Sui-intent-prefixed.
68
+ * `claim_share` calls `ed25519::ed25519_verify` directly, so any
69
+ * intent prefix would break verification.
70
+ */
71
+ export declare function signGiftClaim(giftKeypair: Ed25519Keypair, giftId: string, sender: string): Promise<Uint8Array>;
72
+ /**
73
+ * Compute the `gift_id` that `create_gift` will produce for the given
74
+ * pubkey, offline. No RPC. Mirrors `claimable_link::derive_gift_address`.
75
+ */
76
+ export declare function deriveGiftAddress(client: PredictClient, pubkey: Uint8Array, params?: GiftBaseParams): string;
77
+ export interface CreateGiftParams extends GiftBaseParams, GiftReferralParams, AccountIdentityParams {
78
+ /** wxa account id (`0x2::object::ID`) that owns the source position. */
79
+ sourceAccountId: IdArgument;
80
+ /** Numeric `position_id` of the position to lock. */
81
+ sourcePositionId: bigint | number | string;
82
+ /** 32-byte gift pubkey (from `deriveGiftKeypair(seed).getPublicKey().toRawBytes()`). */
83
+ pubkey: Uint8Array;
84
+ /** Number of slices, 1..=MAX_SHARES_PER_GIFT. */
85
+ shareCount: bigint | number | string;
86
+ /** Absolute expiry in milliseconds. Must be strictly in the future. */
87
+ expiresAtMs: bigint | number | string;
88
+ /** Optional referral code applied to every claimer (idempotent). */
89
+ referralCode?: string | null;
90
+ /** Override `MarketRegistry<T>` id. Defaults to `client.marketRegistry()`. */
91
+ marketRegistry?: string;
92
+ /** Override `AccountRegistry` id. Defaults to `client.accountRegistry()`. */
93
+ accountRegistry?: string;
94
+ }
95
+ /**
96
+ * Lock one position behind `pubkey` and share it as a gift. Adds a
97
+ * single `claimable_link::create_gift<T>` call to `tx` using the
98
+ * caller's `bucket_framework::account::request` as the source-owner
99
+ * authority. The transaction sender (`ctx.sender()`) must be the owner
100
+ * of `sourceAccountId`.
101
+ */
102
+ export declare function createGift(client: PredictClient, tx: Transaction, params: CreateGiftParams): Transaction;
103
+ export interface ClaimShareParams extends GiftBaseParams, GiftReferralParams {
104
+ /** Shared `Gift<T>` object id. Derive locally via `deriveGiftAddress`. */
105
+ giftId: string;
106
+ /** Raw 64-byte Ed25519 signature over `buildGiftClaimMessage(giftId, sender)`. */
107
+ sig: Uint8Array;
108
+ /**
109
+ * Recipient wxa account id, or `null`/`undefined` to land in the
110
+ * claimer's main wxa (auto-created with alias `"main"` if the
111
+ * claimer has none yet).
112
+ */
113
+ recipientAccountId?: IdArgument | null;
114
+ /** prediction `GlobalConfig` id. Defaults to `client.globalConfigId()`. */
115
+ globalConfig?: string;
116
+ /** prediction `MarketRegistry<T>` id. Defaults to `client.marketRegistry()`. */
117
+ marketRegistry?: string;
118
+ /** `waterx_account::AccountRegistry` id. Defaults to `client.accountRegistry()`. */
119
+ accountRegistry?: string;
120
+ }
121
+ /**
122
+ * Claim one slice of a gift. The signature must be raw Ed25519 (NOT
123
+ * Sui-intent-prefixed) over `DOMAIN_CLAIM || gift_id || sender`.
124
+ * Pre-flight: fetch the gift and check `claimed_count < share_count`,
125
+ * `now < expires_at_ms`, and `!claimed_addresses.contains(sender)` to
126
+ * surface "already claimed" client-side instead of paying gas to abort.
127
+ */
128
+ export declare function claimShare(client: PredictClient, tx: Transaction, params: ClaimShareParams): Transaction;
129
+ export interface DeleteGiftParams extends GiftBaseParams, AccountIdentityParams {
130
+ /** Shared `Gift<T>` object id to consume. */
131
+ giftId: string;
132
+ }
133
+ /**
134
+ * Creator-driven hard delete. Consumes the `Gift<T>` by value and
135
+ * removes it from `config.creator_gifts[creator]`. The source position
136
+ * stays on the creator's wxa; nothing to refund. Skips the paused gate
137
+ * — cancel must work even when the package is paused.
138
+ */
139
+ export declare function deleteGift(client: PredictClient, tx: Transaction, params: DeleteGiftParams): Transaction;
140
+ export interface GiftView {
141
+ giftId: string;
142
+ creator: string;
143
+ creatorAccountId: string;
144
+ sourcePositionId: bigint;
145
+ marketId: Uint8Array;
146
+ marketIdHex: string;
147
+ selection: Selection;
148
+ totalSpend: bigint;
149
+ spendPerShare: bigint;
150
+ lockedOddsCents: bigint;
151
+ pubkey: Uint8Array;
152
+ shareCount: bigint;
153
+ claimedCount: bigint;
154
+ claimedAddresses: string[];
155
+ baseShareAmount: bigint;
156
+ extraShareLinks: bigint;
157
+ totalShares: bigint;
158
+ remainingShares: bigint;
159
+ referralCode: string | null;
160
+ createdAtMs: bigint;
161
+ expiresAtMs: bigint;
162
+ }
163
+ /**
164
+ * Fetch a single gift's full view in one RPC by batching every getter
165
+ * into one simulated PTB. Decodes each `commandResults[i].returnValues[0]`
166
+ * into the corresponding TypeScript field.
167
+ */
168
+ export declare function getGift(client: PredictClient, params: GiftBaseParams & {
169
+ giftId: string;
170
+ }): Promise<GiftView>;
171
+ /** Live gift IDs for a creator. Order isn't preserved — sort by `createdAtMs`. */
172
+ export declare function getCreatorGiftIds(client: PredictClient, params: GiftBaseParams & {
173
+ creator: string;
174
+ }): Promise<string[]>;
175
+ export declare function getCreatorGiftCount(client: PredictClient, params: GiftBaseParams & {
176
+ creator: string;
177
+ }): Promise<bigint>;
178
+ /**
179
+ * Global controller delegate address. Same value for every creator,
180
+ * stable for the package's lifetime. Surface on FE so creators can
181
+ * verify the right delegate is registered on their wxa.
182
+ */
183
+ export declare function getGiftControllerAddress(client: PredictClient, params?: GiftBaseParams): Promise<string>;
184
+ export declare function getGiftConfigPaused(client: PredictClient, params?: GiftBaseParams): Promise<boolean>;
185
+ export declare function getGiftHasClaimed(client: PredictClient, params: GiftBaseParams & {
186
+ giftId: string;
187
+ addr: string;
188
+ }): Promise<boolean>;
189
+ export interface BuildCreateGiftFlowResult {
190
+ tx: Transaction;
191
+ /** Raw 16-byte seed. Encode into the share URL with `encodeGiftUrl`. */
192
+ seed: Uint8Array;
193
+ /** Predicted gift ID (computed locally from `(config, pubkey)`). */
194
+ giftId: string;
195
+ /** 32-byte gift pubkey, in case the caller wants to log/store it. */
196
+ pubkey: Uint8Array;
197
+ }
198
+ /**
199
+ * One-shot: generate a fresh seed, derive the gift keypair + pubkey,
200
+ * compute the predicted `gift_id`, and add the `create_gift` call to
201
+ * `tx`. The caller signs + executes `tx` and then renders the URL via
202
+ * `encodeGiftUrl(seed, …)`.
203
+ */
204
+ export declare function buildCreateGiftFlow(client: PredictClient, tx: Transaction, params: Omit<CreateGiftParams, "pubkey">): BuildCreateGiftFlowResult;
205
+ export interface BuildClaimShareFlowParams extends Omit<ClaimShareParams, "sig" | "giftId"> {
206
+ /** The 16-byte seed parsed from the share URL fragment. */
207
+ seed: Uint8Array;
208
+ /** The transaction sender (becomes `ctx.sender()`). Bound into the sig. */
209
+ sender: string;
210
+ /** Optional override — defaults to `deriveGiftAddress(client, pubkey)`. */
211
+ giftId?: string;
212
+ }
213
+ export interface BuildClaimShareFlowResult {
214
+ tx: Transaction;
215
+ giftId: string;
216
+ sig: Uint8Array;
217
+ }
218
+ /**
219
+ * One-shot: derive the gift keypair from `seed`, compute `gift_id`,
220
+ * sign the claim payload bound to `sender`, and add the `claim_share`
221
+ * call to `tx`. Caller signs + executes `tx` with `sender`'s keypair.
222
+ */
223
+ export declare function buildClaimShareFlow(client: PredictClient, tx: Transaction, params: BuildClaimShareFlowParams): Promise<BuildClaimShareFlowResult>;
@@ -0,0 +1,451 @@
1
+ /**
2
+ * waterx_prediction_gift / claimable_link bindings.
3
+ *
4
+ * Three responsibilities:
5
+ *
6
+ * 1. **KDF + signed-message format** — turn a 16-byte URL seed into an
7
+ * Ed25519 keypair (sha256 over a package-prefixed domain) and build
8
+ * the exact 92-byte payload `claim_share` verifies on chain.
9
+ * Every byte here must match `claimable_link.move` — one wrong byte
10
+ * and outstanding URLs break.
11
+ *
12
+ * 2. **URL helpers + offline gift-address derivation** — base64url(no-pad)
13
+ * encode/decode of the seed (URL fragment), and `deriveGiftAddress`
14
+ * which mirrors `derived_object::derive_address` locally so a
15
+ * receiver can compute `gift_id` from the seed without any RPC.
16
+ *
17
+ * 3. **PTB builders + simulate reads** — `createGift` / `claimShare` /
18
+ * `deleteGift` matching the on-chain entrypoints, plus single-RPC
19
+ * `simulateTransaction`-based read helpers for the view fns.
20
+ */
21
+ import { bcs } from "@mysten/sui/bcs";
22
+ import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
23
+ import { Transaction } from "@mysten/sui/transactions";
24
+ import { deriveObjectID, fromBase64, toBase64 } from "@mysten/sui/utils";
25
+ import { sha256 } from "@noble/hashes/sha2.js";
26
+ import { SelectionBcs } from "./bcs.js";
27
+ import { GIFT_DOMAIN_CLAIM, GIFT_KDF_DOMAIN, GIFT_PUBKEY_LEN, GIFT_SIG_LEN, GIFT_URL_SEED_BYTES, } from "./constants.js";
28
+ import { extractReturnBytes } from "./fetch.js";
29
+ import { clockArg, createAccountRequest, idArg, resolveAccountRegistry, resolveGlobalConfig, resolveMarketRegistry, resolveSettlementCoinType, toBigInt, } from "./utils.js";
30
+ function resolveGiftPackageId(client, override) {
31
+ return override === undefined || override === ""
32
+ ? client.waterxPredictionGiftPackageId()
33
+ : override;
34
+ }
35
+ function resolveClaimableLinkConfig(client, override) {
36
+ return override === undefined || override === "" ? client.claimableLinkConfigId() : override;
37
+ }
38
+ function resolveReferralTable(client, override) {
39
+ return override === undefined || override === "" ? client.referralTableId() : override;
40
+ }
41
+ // ---------------------------------------------------------------------
42
+ // URL / base64url(no-pad) helpers
43
+ //
44
+ // Standard base64 maps to base64url by replacing +/= → -_ and dropping
45
+ // padding. Tiny enough to avoid pulling @scure/base.
46
+ // ---------------------------------------------------------------------
47
+ export function base64UrlNoPadEncode(bytes) {
48
+ return toBase64(bytes).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
49
+ }
50
+ export function base64UrlNoPadDecode(value) {
51
+ let b64 = value.replaceAll("-", "+").replaceAll("_", "/");
52
+ while (b64.length % 4 !== 0)
53
+ b64 += "=";
54
+ return fromBase64(b64);
55
+ }
56
+ /** CSPRNG-generated 16-byte URL seed. Uses `globalThis.crypto.getRandomValues`. */
57
+ export function generateGiftSeed() {
58
+ const seed = new Uint8Array(GIFT_URL_SEED_BYTES);
59
+ if (typeof globalThis.crypto?.getRandomValues !== "function") {
60
+ throw new Error("generateGiftSeed: globalThis.crypto.getRandomValues is unavailable; use Node >= 19 or a polyfill");
61
+ }
62
+ globalThis.crypto.getRandomValues(seed);
63
+ return seed;
64
+ }
65
+ /** Build the share URL: `<host><path>#<base64urlnopad(seed)>`. */
66
+ export function encodeGiftUrl(seed, parts = {}) {
67
+ assertSeedLength(seed);
68
+ const host = parts.host ?? "";
69
+ const path = parts.path ?? "/g/";
70
+ return `${host}${path}#${base64UrlNoPadEncode(seed)}`;
71
+ }
72
+ /** Parse a share URL or fragment-only string back into the raw seed bytes. */
73
+ export function parseGiftUrl(url) {
74
+ const hashIdx = url.indexOf("#");
75
+ if (hashIdx === -1) {
76
+ throw new Error("parseGiftUrl: no '#' fragment in URL");
77
+ }
78
+ const fragment = url.slice(hashIdx + 1);
79
+ if (fragment === "")
80
+ throw new Error("parseGiftUrl: empty fragment");
81
+ const seed = base64UrlNoPadDecode(fragment);
82
+ assertSeedLength(seed);
83
+ return { seed };
84
+ }
85
+ function assertSeedLength(seed) {
86
+ if (seed.length !== GIFT_URL_SEED_BYTES) {
87
+ throw new Error(`Gift URL seed must be ${GIFT_URL_SEED_BYTES} bytes, got ${seed.length}`);
88
+ }
89
+ }
90
+ // ---------------------------------------------------------------------
91
+ // KDF + signed-message
92
+ // ---------------------------------------------------------------------
93
+ function concatBytes(...parts) {
94
+ let total = 0;
95
+ for (const p of parts)
96
+ total += p.length;
97
+ const out = new Uint8Array(total);
98
+ let offset = 0;
99
+ for (const p of parts) {
100
+ out.set(p, offset);
101
+ offset += p.length;
102
+ }
103
+ return out;
104
+ }
105
+ /**
106
+ * Off-chain KDF: `sha256(KDF_DOMAIN || seed)` → 32-byte Ed25519 secret.
107
+ * Bytes MUST match across SDK versions and downstream integrations or
108
+ * every outstanding URL breaks.
109
+ */
110
+ export function deriveGiftKeypair(seed) {
111
+ assertSeedLength(seed);
112
+ const secret = sha256(concatBytes(GIFT_KDF_DOMAIN, seed));
113
+ return Ed25519Keypair.fromSecretKey(secret);
114
+ }
115
+ /**
116
+ * Reproduce the bytes `claim_share` verifies:
117
+ * `DOMAIN_CLAIM || bcs(gift_id) || bcs(sender)` = 28 + 32 + 32 = 92 bytes.
118
+ */
119
+ export function buildGiftClaimMessage(giftId, sender) {
120
+ return concatBytes(GIFT_DOMAIN_CLAIM, bcs.Address.serialize(giftId).toBytes(), bcs.Address.serialize(sender).toBytes());
121
+ }
122
+ /**
123
+ * Raw Ed25519 over the claim payload — NOT Sui-intent-prefixed.
124
+ * `claim_share` calls `ed25519::ed25519_verify` directly, so any
125
+ * intent prefix would break verification.
126
+ */
127
+ export async function signGiftClaim(giftKeypair, giftId, sender) {
128
+ const sig = await giftKeypair.sign(buildGiftClaimMessage(giftId, sender));
129
+ if (sig.length !== GIFT_SIG_LEN) {
130
+ throw new Error(`Gift signature must be ${GIFT_SIG_LEN} bytes, got ${sig.length}`);
131
+ }
132
+ return sig;
133
+ }
134
+ // ---------------------------------------------------------------------
135
+ // Offline gift-address derivation
136
+ //
137
+ // Mirrors `derived_object::derive_address(parent_id, GiftKey { pubkey })`.
138
+ // `deriveObjectID` from @mysten/sui/utils wraps the key in
139
+ // `DerivedObjectKey<K>` and hashes parent_id || type_tag || bcs(key)
140
+ // with blake2b-256, which matches the on-chain formula.
141
+ // ---------------------------------------------------------------------
142
+ const GiftKeyBcs = bcs.struct("GiftKey", {
143
+ pubkey: bcs.vector(bcs.u8()),
144
+ });
145
+ /**
146
+ * Compute the `gift_id` that `create_gift` will produce for the given
147
+ * pubkey, offline. No RPC. Mirrors `claimable_link::derive_gift_address`.
148
+ */
149
+ export function deriveGiftAddress(client, pubkey, params = {}) {
150
+ if (pubkey.length !== GIFT_PUBKEY_LEN) {
151
+ throw new Error(`Gift pubkey must be ${GIFT_PUBKEY_LEN} bytes, got ${pubkey.length}`);
152
+ }
153
+ const giftPkg = resolveGiftPackageId(client, params.giftPackageId);
154
+ const configId = resolveClaimableLinkConfig(client, params.claimableLinkConfig);
155
+ const keyBytes = GiftKeyBcs.serialize({ pubkey: Array.from(pubkey) }).toBytes();
156
+ return deriveObjectID(configId, `${giftPkg}::claimable_link::GiftKey`, keyBytes);
157
+ }
158
+ /**
159
+ * Lock one position behind `pubkey` and share it as a gift. Adds a
160
+ * single `claimable_link::create_gift<T>` call to `tx` using the
161
+ * caller's `bucket_framework::account::request` as the source-owner
162
+ * authority. The transaction sender (`ctx.sender()`) must be the owner
163
+ * of `sourceAccountId`.
164
+ */
165
+ export function createGift(client, tx, params) {
166
+ if (params.pubkey.length !== GIFT_PUBKEY_LEN) {
167
+ throw new Error(`createGift: pubkey must be ${GIFT_PUBKEY_LEN} bytes, got ${params.pubkey.length}`);
168
+ }
169
+ const giftPkg = resolveGiftPackageId(client, params.giftPackageId);
170
+ const coinType = resolveSettlementCoinType(client, params.settlementCoinType);
171
+ const sourceOwnerRequest = createAccountRequest(client, tx, params);
172
+ tx.moveCall({
173
+ target: `${giftPkg}::claimable_link::create_gift`,
174
+ typeArguments: [coinType],
175
+ arguments: [
176
+ tx.object(resolveClaimableLinkConfig(client, params.claimableLinkConfig)),
177
+ tx.object(resolveMarketRegistry(client, params.marketRegistry)),
178
+ tx.object(resolveAccountRegistry(client, params.accountRegistry)),
179
+ tx.object(resolveReferralTable(client, params.referralTable)),
180
+ sourceOwnerRequest,
181
+ idArg(tx, params.sourceAccountId),
182
+ tx.pure.u64(toBigInt(params.sourcePositionId)),
183
+ tx.pure.vector("u8", Array.from(params.pubkey)),
184
+ tx.pure.u64(toBigInt(params.shareCount)),
185
+ tx.pure.u64(toBigInt(params.expiresAtMs)),
186
+ tx.pure.option("string", params.referralCode ?? null),
187
+ clockArg(tx),
188
+ ],
189
+ });
190
+ return tx;
191
+ }
192
+ /**
193
+ * Claim one slice of a gift. The signature must be raw Ed25519 (NOT
194
+ * Sui-intent-prefixed) over `DOMAIN_CLAIM || gift_id || sender`.
195
+ * Pre-flight: fetch the gift and check `claimed_count < share_count`,
196
+ * `now < expires_at_ms`, and `!claimed_addresses.contains(sender)` to
197
+ * surface "already claimed" client-side instead of paying gas to abort.
198
+ */
199
+ export function claimShare(client, tx, params) {
200
+ if (params.sig.length !== GIFT_SIG_LEN) {
201
+ throw new Error(`claimShare: sig must be ${GIFT_SIG_LEN} bytes, got ${params.sig.length}`);
202
+ }
203
+ const giftPkg = resolveGiftPackageId(client, params.giftPackageId);
204
+ const coinType = resolveSettlementCoinType(client, params.settlementCoinType);
205
+ // recipient_account_id is `Option<ID>` — tx.pure.option only accepts a
206
+ // string literal id, so a TransactionArgument here would need a
207
+ // different code path (build the Option via Move calls). Bail loudly.
208
+ if (params.recipientAccountId !== undefined &&
209
+ params.recipientAccountId !== null &&
210
+ typeof params.recipientAccountId !== "string") {
211
+ throw new Error("claimShare: recipientAccountId must be a string id or null/undefined");
212
+ }
213
+ tx.moveCall({
214
+ target: `${giftPkg}::claimable_link::claim_share`,
215
+ typeArguments: [coinType],
216
+ arguments: [
217
+ tx.object(resolveClaimableLinkConfig(client, params.claimableLinkConfig)),
218
+ tx.object(params.giftId),
219
+ tx.object(resolveGlobalConfig(client, params.globalConfig)),
220
+ tx.object(resolveMarketRegistry(client, params.marketRegistry)),
221
+ tx.object(resolveAccountRegistry(client, params.accountRegistry)),
222
+ tx.object(resolveReferralTable(client, params.referralTable)),
223
+ tx.pure.option("id", params.recipientAccountId ?? null),
224
+ tx.pure.vector("u8", Array.from(params.sig)),
225
+ clockArg(tx),
226
+ ],
227
+ });
228
+ return tx;
229
+ }
230
+ /**
231
+ * Creator-driven hard delete. Consumes the `Gift<T>` by value and
232
+ * removes it from `config.creator_gifts[creator]`. The source position
233
+ * stays on the creator's wxa; nothing to refund. Skips the paused gate
234
+ * — cancel must work even when the package is paused.
235
+ */
236
+ export function deleteGift(client, tx, params) {
237
+ const giftPkg = resolveGiftPackageId(client, params.giftPackageId);
238
+ const coinType = resolveSettlementCoinType(client, params.settlementCoinType);
239
+ const creatorRequest = createAccountRequest(client, tx, params);
240
+ tx.moveCall({
241
+ target: `${giftPkg}::claimable_link::delete_gift`,
242
+ typeArguments: [coinType],
243
+ arguments: [
244
+ tx.object(resolveClaimableLinkConfig(client, params.claimableLinkConfig)),
245
+ tx.object(params.giftId),
246
+ creatorRequest,
247
+ clockArg(tx),
248
+ ],
249
+ });
250
+ return tx;
251
+ }
252
+ /**
253
+ * Fetch a single gift's full view in one RPC by batching every getter
254
+ * into one simulated PTB. Decodes each `commandResults[i].returnValues[0]`
255
+ * into the corresponding TypeScript field.
256
+ */
257
+ export async function getGift(client, params) {
258
+ const giftPkg = resolveGiftPackageId(client, params.giftPackageId);
259
+ const coinType = resolveSettlementCoinType(client, params.settlementCoinType);
260
+ const tx = new Transaction();
261
+ const giftArg = tx.object(params.giftId);
262
+ // Ordering is load-bearing: result decoders below index by command position.
263
+ const callGetter = (name) => {
264
+ tx.moveCall({
265
+ target: `${giftPkg}::claimable_link::${name}`,
266
+ typeArguments: [coinType],
267
+ arguments: [giftArg],
268
+ });
269
+ };
270
+ const getterOrder = [
271
+ "gift_id",
272
+ "creator",
273
+ "creator_account_id",
274
+ "source_position_id",
275
+ "market_id",
276
+ "selection",
277
+ "total_spend",
278
+ "spend_per_share",
279
+ "locked_odds_cents",
280
+ "pubkey",
281
+ "share_count",
282
+ "claimed_count",
283
+ "claimed_addresses",
284
+ "base_share_amount",
285
+ "extra_share_links",
286
+ "total_shares",
287
+ "remaining_shares",
288
+ "referral_code",
289
+ "created_at_ms",
290
+ "expires_at_ms",
291
+ ];
292
+ for (const g of getterOrder)
293
+ callGetter(g);
294
+ const result = await client.simulate(tx);
295
+ let i = 0;
296
+ const id = () => bcs.Address.parse(extractReturnBytes(result, i++));
297
+ const u64 = () => BigInt(bcs.u64().parse(extractReturnBytes(result, i++)));
298
+ const bytes = () => new Uint8Array(bcs.vector(bcs.u8()).parse(extractReturnBytes(result, i++)));
299
+ const sel = () => {
300
+ const parsed = SelectionBcs.parse(extractReturnBytes(result, i++));
301
+ const variant = parsed?.$kind ?? parsed; // bcs.enum returns { $kind } in v2
302
+ if (variant === "Yes" || variant === "YES")
303
+ return "YES";
304
+ if (variant === "No" || variant === "NO")
305
+ return "NO";
306
+ throw new Error(`Unrecognized Selection variant: ${JSON.stringify(parsed)}`);
307
+ };
308
+ const addrs = () => bcs.vector(bcs.Address).parse(extractReturnBytes(result, i++));
309
+ const optString = () => bcs.option(bcs.string()).parse(extractReturnBytes(result, i++));
310
+ const giftId = id();
311
+ const creator = id();
312
+ const creatorAccountId = id();
313
+ const sourcePositionId = u64();
314
+ const marketIdBytes = bytes();
315
+ const selection = sel();
316
+ const totalSpend = u64();
317
+ const spendPerShare = u64();
318
+ const lockedOddsCents = u64();
319
+ const pubkey = bytes();
320
+ const shareCount = u64();
321
+ const claimedCount = u64();
322
+ const claimedAddresses = addrs();
323
+ const baseShareAmount = u64();
324
+ const extraShareLinks = u64();
325
+ const totalShares = u64();
326
+ const remainingShares = u64();
327
+ const referralCode = optString();
328
+ const createdAtMs = u64();
329
+ const expiresAtMs = u64();
330
+ return {
331
+ giftId,
332
+ creator,
333
+ creatorAccountId,
334
+ sourcePositionId,
335
+ marketId: marketIdBytes,
336
+ marketIdHex: bytesToHexLocal(marketIdBytes),
337
+ selection,
338
+ totalSpend,
339
+ spendPerShare,
340
+ lockedOddsCents,
341
+ pubkey,
342
+ shareCount,
343
+ claimedCount,
344
+ claimedAddresses,
345
+ baseShareAmount,
346
+ extraShareLinks,
347
+ totalShares,
348
+ remainingShares,
349
+ referralCode: referralCode ?? null,
350
+ createdAtMs,
351
+ expiresAtMs,
352
+ };
353
+ }
354
+ // Local copy of the hex helper to avoid a circular import via utils.ts.
355
+ function bytesToHexLocal(bytes) {
356
+ let out = "0x";
357
+ for (const b of bytes)
358
+ out += b.toString(16).padStart(2, "0");
359
+ return out;
360
+ }
361
+ /** Live gift IDs for a creator. Order isn't preserved — sort by `createdAtMs`. */
362
+ export async function getCreatorGiftIds(client, params) {
363
+ const giftPkg = resolveGiftPackageId(client, params.giftPackageId);
364
+ const tx = new Transaction();
365
+ tx.moveCall({
366
+ target: `${giftPkg}::claimable_link::creator_gift_ids`,
367
+ arguments: [
368
+ tx.object(resolveClaimableLinkConfig(client, params.claimableLinkConfig)),
369
+ tx.pure.address(params.creator),
370
+ ],
371
+ });
372
+ const result = await client.simulate(tx);
373
+ return bcs.vector(bcs.Address).parse(extractReturnBytes(result));
374
+ }
375
+ export async function getCreatorGiftCount(client, params) {
376
+ const giftPkg = resolveGiftPackageId(client, params.giftPackageId);
377
+ const tx = new Transaction();
378
+ tx.moveCall({
379
+ target: `${giftPkg}::claimable_link::creator_gift_count`,
380
+ arguments: [
381
+ tx.object(resolveClaimableLinkConfig(client, params.claimableLinkConfig)),
382
+ tx.pure.address(params.creator),
383
+ ],
384
+ });
385
+ const result = await client.simulate(tx);
386
+ return BigInt(bcs.u64().parse(extractReturnBytes(result)));
387
+ }
388
+ /**
389
+ * Global controller delegate address. Same value for every creator,
390
+ * stable for the package's lifetime. Surface on FE so creators can
391
+ * verify the right delegate is registered on their wxa.
392
+ */
393
+ export async function getGiftControllerAddress(client, params = {}) {
394
+ const giftPkg = resolveGiftPackageId(client, params.giftPackageId);
395
+ const tx = new Transaction();
396
+ tx.moveCall({
397
+ target: `${giftPkg}::claimable_link::controller_address`,
398
+ arguments: [tx.object(resolveClaimableLinkConfig(client, params.claimableLinkConfig))],
399
+ });
400
+ const result = await client.simulate(tx);
401
+ return bcs.Address.parse(extractReturnBytes(result));
402
+ }
403
+ export async function getGiftConfigPaused(client, params = {}) {
404
+ const giftPkg = resolveGiftPackageId(client, params.giftPackageId);
405
+ const tx = new Transaction();
406
+ tx.moveCall({
407
+ target: `${giftPkg}::claimable_link::is_paused`,
408
+ arguments: [tx.object(resolveClaimableLinkConfig(client, params.claimableLinkConfig))],
409
+ });
410
+ const result = await client.simulate(tx);
411
+ return bcs.bool().parse(extractReturnBytes(result));
412
+ }
413
+ export async function getGiftHasClaimed(client, params) {
414
+ const giftPkg = resolveGiftPackageId(client, params.giftPackageId);
415
+ const coinType = resolveSettlementCoinType(client, params.settlementCoinType);
416
+ const tx = new Transaction();
417
+ tx.moveCall({
418
+ target: `${giftPkg}::claimable_link::has_claimed`,
419
+ typeArguments: [coinType],
420
+ arguments: [tx.object(params.giftId), tx.pure.address(params.addr)],
421
+ });
422
+ const result = await client.simulate(tx);
423
+ return bcs.bool().parse(extractReturnBytes(result));
424
+ }
425
+ /**
426
+ * One-shot: generate a fresh seed, derive the gift keypair + pubkey,
427
+ * compute the predicted `gift_id`, and add the `create_gift` call to
428
+ * `tx`. The caller signs + executes `tx` and then renders the URL via
429
+ * `encodeGiftUrl(seed, …)`.
430
+ */
431
+ export function buildCreateGiftFlow(client, tx, params) {
432
+ const seed = generateGiftSeed();
433
+ const giftKeypair = deriveGiftKeypair(seed);
434
+ const pubkey = giftKeypair.getPublicKey().toRawBytes();
435
+ const giftId = deriveGiftAddress(client, pubkey, params);
436
+ createGift(client, tx, { ...params, pubkey });
437
+ return { tx, seed, giftId, pubkey };
438
+ }
439
+ /**
440
+ * One-shot: derive the gift keypair from `seed`, compute `gift_id`,
441
+ * sign the claim payload bound to `sender`, and add the `claim_share`
442
+ * call to `tx`. Caller signs + executes `tx` with `sender`'s keypair.
443
+ */
444
+ export async function buildClaimShareFlow(client, tx, params) {
445
+ const giftKeypair = deriveGiftKeypair(params.seed);
446
+ const pubkey = giftKeypair.getPublicKey().toRawBytes();
447
+ const giftId = params.giftId ?? deriveGiftAddress(client, pubkey, params);
448
+ const sig = await signGiftClaim(giftKeypair, giftId, params.sender);
449
+ claimShare(client, tx, { ...params, giftId, sig });
450
+ return { tx, giftId, sig };
451
+ }