@flayerlabs/gamemode-gate 0.4.2 → 0.5.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 (63) hide show
  1. package/DEPLOY.md +27 -3
  2. package/README.md +3 -3
  3. package/dist/chain/chains.d.ts +45 -6
  4. package/dist/chain/chains.d.ts.map +1 -1
  5. package/dist/chain/chains.js +56 -5
  6. package/dist/chain/chains.js.map +1 -1
  7. package/dist/chain/discover.d.ts +20 -2
  8. package/dist/chain/discover.d.ts.map +1 -1
  9. package/dist/chain/discover.js +74 -6
  10. package/dist/chain/discover.js.map +1 -1
  11. package/dist/chain/secure.d.ts +11 -1
  12. package/dist/chain/secure.d.ts.map +1 -1
  13. package/dist/chain/secure.js +67 -0
  14. package/dist/chain/secure.js.map +1 -1
  15. package/dist/claims.d.ts +1 -1
  16. package/dist/claims.d.ts.map +1 -1
  17. package/dist/claims.js +2 -2
  18. package/dist/claims.js.map +1 -1
  19. package/dist/demo.d.ts +1 -1
  20. package/dist/demo.d.ts.map +1 -1
  21. package/dist/demo.js +9 -9
  22. package/dist/demo.js.map +1 -1
  23. package/dist/economy.d.ts +25 -9
  24. package/dist/economy.d.ts.map +1 -1
  25. package/dist/economy.js +63 -22
  26. package/dist/economy.js.map +1 -1
  27. package/dist/index.d.ts +6 -6
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +3 -3
  30. package/dist/index.js.map +1 -1
  31. package/dist/ledger.d.ts +2 -2
  32. package/dist/ledger.d.ts.map +1 -1
  33. package/dist/ledger.js +16 -16
  34. package/dist/ledger.js.map +1 -1
  35. package/dist/main.d.ts +30 -5
  36. package/dist/main.d.ts.map +1 -1
  37. package/dist/main.js +158 -17
  38. package/dist/main.js.map +1 -1
  39. package/dist/room.d.ts +7 -4
  40. package/dist/room.d.ts.map +1 -1
  41. package/dist/room.js +31 -10
  42. package/dist/room.js.map +1 -1
  43. package/dist/server.d.ts +33 -3
  44. package/dist/server.d.ts.map +1 -1
  45. package/dist/server.js +63 -25
  46. package/dist/server.js.map +1 -1
  47. package/dist/store.d.ts +1 -1
  48. package/dist/store.d.ts.map +1 -1
  49. package/dist/store.js +21 -0
  50. package/dist/store.js.map +1 -1
  51. package/package.json +2 -2
  52. package/src/chain/chains.ts +82 -9
  53. package/src/chain/discover.ts +87 -7
  54. package/src/chain/secure.ts +86 -1
  55. package/src/claims.ts +2 -2
  56. package/src/demo.ts +10 -10
  57. package/src/economy.ts +83 -31
  58. package/src/index.ts +7 -5
  59. package/src/ledger.ts +18 -18
  60. package/src/main.ts +181 -19
  61. package/src/room.ts +41 -14
  62. package/src/server.ts +107 -35
  63. package/src/store.ts +21 -0
package/DEPLOY.md CHANGED
@@ -38,12 +38,34 @@ gate whose signatures a swap can actually verify.
38
38
  | `GATE_ORIGIN` | yes | This gate's own public https origin (e.g. `https://gate.example.com`) — the audience its sessions are scoped to. Configured, never derived from a request header. |
39
39
  | `ALLOWED_ORIGINS` | yes | Comma-separated origins allowed to call this gate: your game's Moongate origin(s) AND every page that embeds it — the coin page calls `/rounds/adopt` itself. Production is `https://flaunch.gg`; a staging or preview launch page has its own origin and needs listing while you test against it. A launch that fails with a CORS error names the missing origin in its `Referer`. |
40
40
  | `PORT` | no | Default `8790`. |
41
- | `POSITION_MANAGER`, `SPEND_GATED_CALCULATOR` | no | Address-book overrides. Set both only with addresses read back from the chain in question — a wrong address fails silently (see `chain/chains.ts`). |
41
+ | `POSITION_MANAGER`, `SPEND_GATED_CALCULATOR` | no | Which recorded stack this gate serves, or address-book overrides. Naming a recorded manager selects its whole stack (calculator and router with it): on Base Sepolia `0x8D346f24278C5CD786309161aAC0fC2bbe4c25dc` is the paired-token stack, the one that can host coins paired with MUSD and other non-ETH tokens. Unset means the legacy stack. Override both only with addresses read back from the chain in question — a wrong address fails silently (see `chain/chains.ts`). |
42
+ | `POOL_SWAP`, `FLETH` | no | Address-book overrides for the paired stack's approved swap router and the chain's flETH wrapper. A `v1_3` stack needs a router. |
43
+ | `FLAUNCH_VARIANT` | no | `v1_2`, `multichain` or `v1_3`; recorded per stack, override only with the overrides above. |
42
44
  | `SETTLER` | no | The address that may lift the gate early or rotate the signer on-chain. Defaults to the signing key's address; the gate expires on chain by itself either way. |
43
- | `WALLET_CAP_WEI` | no | Advertised per-wallet cap for launches through this gate. Default 0.025 ETH. |
45
+ | `WALLET_CAP_WEI` | no | Advertised per-wallet cap for ETH-paired launches through this gate, in wei. Default 0.025 ETH. |
44
46
  | `ROUND_MS` | no | Advertised round length. Default 90000. |
45
47
  | `MIN_LOBBY_LEAD_MS`, `GATE_ENDS_AT_GRACE_S` | no | Defaults 60000 and 10. |
46
- | `POINTS_PER_DOLLAR`, `USD_PER_ETH` | no | Your game's economy. Defaults 100 and 3000; boot refuses an economy your `rewardBounds` cannot honour. |
48
+ | `POINTS_PER_DOLLAR`, `USD_PER_ETH` | no | Your game's economy. Defaults 100 and 3000; `USD_PER_ETH` may be fractional. Boot refuses an economy your `rewardBounds` cannot honour. |
49
+ | `SPEND_TOKENS` | no | The non-ETH paired tokens this gate runs rounds on: a JSON array of `{ "address", "usdPerToken", "walletCap" }`, the cap in that token's base units. Symbol and decimals are read from the chain at boot, and boot refuses an economy the cap cannot honour. A launch paired with a token not listed here is refused at adoption — the gate never guesses a price. Needs the paired stack (`POSITION_MANAGER` above). |
50
+
51
+ ## Paired-token rounds
52
+
53
+ A coin's spend is measured on chain in its paired token's own base units, so a round on a coin
54
+ paired with MUSD (six decimals) counts millionths of a dollar where an ETH round counts wei. The gate
55
+ prices each round in the token the chain reports, and everything `*Wei`-named on the wire is in
56
+ that token's units. Two things make a gate able to host them:
57
+
58
+ 1. Serve the paired stack: `POSITION_MANAGER=0x8D346f24278C5CD786309161aAC0fC2bbe4c25dc` on Base
59
+ Sepolia. That manager also hosts flETH and native-ETH pairings, so the same gate still runs ETH
60
+ rounds. Boot reads the stack's wiring back (dispatcher registration, the calculator's role grant,
61
+ the router approval) and refuses with the missing call named if any is absent.
62
+ 2. List the tokens in `SPEND_TOKENS`. `/config` then announces them under `spendTokens`, which is
63
+ what the launch page checks a pairing against before any coin is paid for.
64
+
65
+ Release 0.5.0 removed `usdPerEth` from the wire along with the rest of the ETH-flavoured naming.
66
+ Round terms now always carry `spendToken` (symbol, decimals, address) and `usdPerSpendToken`, the
67
+ token's own price, and every amount is in that token's base units. Games built against 0.4.x must
68
+ be updated; see MIGRATING.md for the rename table.
47
69
 
48
70
  ## Railway shape
49
71
 
@@ -60,6 +82,8 @@ gate whose signatures a swap can actually verify.
60
82
  ```
61
83
  curl https://<gate>/health → { "ok": true }
62
84
  curl https://<gate>/config → chainId must be the chain you meant; note "signer"
85
+ a paired stack shows flaunchVariant "v1_3", contracts.poolSwap
86
+ and a spendTokens list
63
87
  ```
64
88
 
65
89
  The `signer` in `/config` is the address a launch must name for this gate to adopt it — the create
package/README.md CHANGED
@@ -56,7 +56,7 @@ A `createGate` setup needs:
56
56
 
57
57
  - `Sessions` configured with the page domain and the gate's exact public origin
58
58
  - `Claims`, `Ledger` and `PayloadSigner` for spending authorisations
59
- - `pointsPerDollar`, `usdPerEth` and the allowed game origins
59
+ - `pointsPerDollar`, `usdPerEth` (the ETH pairing's price) and the allowed game origins
60
60
 
61
61
  Add the chain services used by your deployment:
62
62
 
@@ -116,11 +116,11 @@ const app = createGameServerGate({
116
116
  },
117
117
  signer: signerAddress,
118
118
  settler: signerAddress,
119
- walletCapWei: '25000000000000000',
119
+ walletCap: '25000000000000000',
120
120
  roundDurationMs: 90_000,
121
121
  minLobbyLeadMs: 60_000,
122
122
  gateEndsAtGraceS: 10,
123
- flaunchVariant: 'legacy11',
123
+ flaunchVariant: 'v1_2',
124
124
  requiresEoa: false,
125
125
  accepting: true,
126
126
  publicLaunchesOpen: true,
@@ -13,18 +13,57 @@
13
13
  * gated on the audit and the multisig handover. Robinhood (4663) is deliberately missing too —
14
14
  * that chain is served by the legacy gate, and this library refusing it keeps the two stacks from
15
15
  * being pointed at each other by a copied env file.
16
+ *
17
+ * One gate serves exactly ONE (positionManager, spendGatedCalculator) pair. The EIP-712 domain of
18
+ * every authorisation binds it to the calculator address, so a signature minted for one pair is
19
+ * meaningless to the other — a gate cannot straddle two stacks, and this book records each stack
20
+ * as its own entry rather than pretending a chain has one.
21
+ */
22
+ /**
23
+ * Which launch generation the stack's PositionManager belongs to.
24
+ *
25
+ * The names match `FlaunchVersion` in `@flaunch/sdk`, because they name the same generations and
26
+ * two vocabularies for one thing is how a gate ends up configured against the wrong ABI. Each
27
+ * generation takes a different `flaunch()` struct, and getting it wrong is an ABI revert at launch
28
+ * time, so it is recorded per stack rather than guessed.
29
+ *
30
+ * v1_2 — the original Base stack. Carries the two fair-launch fields; flETH pairing only.
31
+ * multichain — the multichain deployment, with the fair-launch fields removed.
32
+ * v1_3 — the current generation, launched through the V1_3 FlaunchZap. The only one that
33
+ * can pair a coin with a token other than ETH, and therefore the only one that can
34
+ * run a paired-token round.
16
35
  */
36
+ export type FlaunchVariant = 'v1_2' | 'multichain' | 'v1_3';
17
37
  export interface GateDeployment {
18
38
  positionManager: `0x${string}`;
19
39
  spendGatedCalculator: `0x${string}`;
40
+ flaunchVariant: FlaunchVariant;
41
+ /**
42
+ * The single-pool swap router the calculator has approved, when the stack has one. A paired-token
43
+ * buy goes through it (ERC20 in, `hookData` carrying the authorisation), and the calculator binds
44
+ * the buyer to its `msgSender()` — so an unapproved router means every smart-wallet buy reverts.
45
+ * Required for `v1_3`; boot refuses a paired stack without it.
46
+ */
47
+ poolSwap?: `0x${string}`;
20
48
  /**
21
- * Which `flaunch()` struct the chain's PositionManager takes. V1_2 deployments carry two extra
22
- * fair-launch fields ('legacy11'); the newer nine-field shape is 'current9'. Getting this wrong
23
- * is an ABI revert at launch time, so it is recorded per chain rather than guessed.
49
+ * The chain's flETH wrapper. A coin paired with it is an ETH round priced at `USD_PER_ETH`, and
50
+ * the wrapper is not the zero address, so the gate has to be told which address means "ETH".
24
51
  */
25
- flaunchVariant: 'legacy11' | 'current9';
52
+ fleth?: `0x${string}`;
26
53
  }
54
+ /** The legacy stack per chain — what `deploymentFor(chainId)` answers with no manager named. */
27
55
  export declare const DEPLOYMENTS: Record<number, GateDeployment>;
28
- /** The deployment for a chain, or undefined for one this library has no address book for. */
29
- export declare function deploymentFor(chainId: number): GateDeployment | undefined;
56
+ /**
57
+ * The paired-token stacks per chain — selected by naming their PositionManager in
58
+ * `POSITION_MANAGER`.
59
+ */
60
+ export declare const PAIRED_DEPLOYMENTS: Record<number, GateDeployment>;
61
+ /**
62
+ * The deployment for a chain, or undefined for one this library has no address book for.
63
+ *
64
+ * With no manager named, the legacy stack. Naming one selects whichever recorded stack it belongs
65
+ * to — so `POSITION_MANAGER=0x8D34…` on Base Sepolia picks the paired stack, calculator and router
66
+ * included, rather than pairing a paired manager with the legacy calculator by accident.
67
+ */
68
+ export declare function deploymentFor(chainId: number, positionManager?: `0x${string}` | null): GateDeployment | undefined;
30
69
  //# sourceMappingURL=chains.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../../src/chain/chains.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,KAAK,MAAM,EAAE,CAAC;IAC/B,oBAAoB,EAAE,KAAK,MAAM,EAAE,CAAC;IACpC;;;;OAIG;IACH,cAAc,EAAE,UAAU,GAAG,UAAU,CAAC;CACzC;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAWtD,CAAC;AAEF,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEzE"}
1
+ {"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../../src/chain/chains.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,YAAY,GAAG,MAAM,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,KAAK,MAAM,EAAE,CAAC;IAC/B,oBAAoB,EAAE,KAAK,MAAM,EAAE,CAAC;IACpC,cAAc,EAAE,cAAc,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IACzB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;CACvB;AAED,gGAAgG;AAChG,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAYtD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CA0B7D,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,KAAK,MAAM,EAAE,GAAG,IAAI,GAAG,cAAc,GAAG,SAAS,CAOjH"}
@@ -13,21 +13,72 @@
13
13
  * gated on the audit and the multisig handover. Robinhood (4663) is deliberately missing too —
14
14
  * that chain is served by the legacy gate, and this library refusing it keeps the two stacks from
15
15
  * being pointed at each other by a copied env file.
16
+ *
17
+ * One gate serves exactly ONE (positionManager, spendGatedCalculator) pair. The EIP-712 domain of
18
+ * every authorisation binds it to the calculator address, so a signature minted for one pair is
19
+ * meaningless to the other — a gate cannot straddle two stacks, and this book records each stack
20
+ * as its own entry rather than pretending a chain has one.
16
21
  */
22
+ /** The legacy stack per chain — what `deploymentFor(chainId)` answers with no manager named. */
17
23
  export const DEPLOYMENTS = {
18
24
  /**
19
- * Base Sepolia — the reference chain. Deployed 2026-08-16 (flaunch-contracts
25
+ * Base Sepolia — the reference chain, V1_2 stack. Deployed 2026-08-16 (flaunch-contracts
20
26
  * SpendGatedGate.s.sol); both PositionManager fee-calculator slots were read back holding the
21
27
  * dispatcher, and the calculator resolves each pool's own paired token (VPT-13).
22
28
  */
23
29
  84532: {
24
30
  positionManager: '0x4E7cB1e6800a7B297B38BddcecAF9Ca5b6616FDC',
25
31
  spendGatedCalculator: '0x8cbbE6b4cFA5Ccf68399Dbf1429d91A21097ebA5',
26
- flaunchVariant: 'legacy11',
32
+ flaunchVariant: 'v1_2',
33
+ fleth: '0x79FC52701cD4BE6f9Ba9aDC94c207DE37e3314eb',
27
34
  },
28
35
  };
29
- /** The deployment for a chain, or undefined for one this library has no address book for. */
30
- export function deploymentFor(chainId) {
31
- return DEPLOYMENTS[chainId];
36
+ /**
37
+ * The paired-token stacks per chain — selected by naming their PositionManager in
38
+ * `POSITION_MANAGER`.
39
+ */
40
+ export const PAIRED_DEPLOYMENTS = {
41
+ /**
42
+ * Base Sepolia — the V1_3 v1.3.3 paired-token stack (flaunch-contracts regeneration, deployed
43
+ * 2026-09-03, blocks 46349133–46349202; `@flaunch/sdk` 0.11.4 launches here). Read back
44
+ * 2026-09-04: the manager's `feeCalculator()` is the dispatcher
45
+ * `0xd381f8ea57df43c57cfe6e5b19a0a4700396f28c`, which has this calculator registered; the
46
+ * calculator grants that dispatcher the PositionManager role and has this PoolSwap approved as a
47
+ * router. This is the stack that hosts a coin paired with MUSD
48
+ * (`0xd0B4398976572515a269C6331A143e08a70E9ccC`, six decimals, approved on the retained registry
49
+ * `0x23cb441d18ca75c6a14964b06806df668d45a1c6`) — and flETH and native ETH pairings too, so a gate
50
+ * on it serves ETH rounds as well.
51
+ *
52
+ * SUPERSEDED, recorded so nobody re-adds it by mistake: the `.vpt2` stack (2026-08-06) —
53
+ * PositionManager `0x5558e7271ec2e8b2faaf05f0eedab1cd986be5dc`, calculator
54
+ * `0x2c9127654ded3b6b2ba017e84f44b02cafdf9f55`, PoolSwap `0x62eb5b7b066ff80ce5e32ff1ed42b31c485f716b`.
55
+ * Its pools keep trading on their own hook and gate, but new paired launches land on the v1.3.3
56
+ * manager, and router approval is PER calculator: `0x62eb…` is NOT approved on the v1.3.3 gate,
57
+ * so pointing this entry at the old router would make every smart-wallet buy revert.
58
+ */
59
+ 84532: {
60
+ positionManager: '0x8D346f24278C5CD786309161aAC0fC2bbe4c25dc',
61
+ spendGatedCalculator: '0x54cdcf0bcbc3a33f470e07134c10582f93058a32',
62
+ flaunchVariant: 'v1_3',
63
+ poolSwap: '0xf0f388a31a1745a5e2378b812ed51525f70595be',
64
+ fleth: '0x79FC52701cD4BE6f9Ba9aDC94c207DE37e3314eb',
65
+ },
66
+ };
67
+ /**
68
+ * The deployment for a chain, or undefined for one this library has no address book for.
69
+ *
70
+ * With no manager named, the legacy stack. Naming one selects whichever recorded stack it belongs
71
+ * to — so `POSITION_MANAGER=0x8D34…` on Base Sepolia picks the paired stack, calculator and router
72
+ * included, rather than pairing a paired manager with the legacy calculator by accident.
73
+ */
74
+ export function deploymentFor(chainId, positionManager) {
75
+ if (!positionManager)
76
+ return DEPLOYMENTS[chainId];
77
+ const wanted = positionManager.toLowerCase();
78
+ for (const candidate of [DEPLOYMENTS[chainId], PAIRED_DEPLOYMENTS[chainId]]) {
79
+ if (candidate && candidate.positionManager.toLowerCase() === wanted)
80
+ return candidate;
81
+ }
82
+ return undefined;
32
83
  }
33
84
  //# sourceMappingURL=chains.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chains.js","sourceRoot":"","sources":["../../src/chain/chains.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAaH,MAAM,CAAC,MAAM,WAAW,GAAmC;IACzD;;;;OAIG;IACH,KAAK,EAAE;QACL,eAAe,EAAE,4CAA4C;QAC7D,oBAAoB,EAAE,4CAA4C;QAClE,cAAc,EAAE,UAAU;KAC3B;CACF,CAAC;AAEF,6FAA6F;AAC7F,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"chains.js","sourceRoot":"","sources":["../../src/chain/chains.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAoCH,gGAAgG;AAChG,MAAM,CAAC,MAAM,WAAW,GAAmC;IACzD;;;;OAIG;IACH,KAAK,EAAE;QACL,eAAe,EAAE,4CAA4C;QAC7D,oBAAoB,EAAE,4CAA4C;QAClE,cAAc,EAAE,MAAM;QACtB,KAAK,EAAE,4CAA4C;KACpD;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAmC;IAChE;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,EAAE;QACL,eAAe,EAAE,4CAA4C;QAC7D,oBAAoB,EAAE,4CAA4C;QAClE,cAAc,EAAE,MAAM;QACtB,QAAQ,EAAE,4CAA4C;QACtD,KAAK,EAAE,4CAA4C;KACpD;CACF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,eAAsC;IACnF,IAAI,CAAC,eAAe;QAAE,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,EAAE,CAAC;IAC7C,KAAK,MAAM,SAAS,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QAC5E,IAAI,SAAS,IAAI,SAAS,CAAC,eAAe,CAAC,WAAW,EAAE,KAAK,MAAM;YAAE,OAAO,SAAS,CAAC;IACxF,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { type PublicClient } from 'viem';
2
+ import { type SpendToken } from '@flayerlabs/gamemode-spec/live';
2
3
  /**
3
4
  * All this needs of a client: the ability to read a contract.
4
5
  *
@@ -46,6 +47,17 @@ export declare const positionManagerAbi: readonly [{
46
47
  readonly outputs: readonly [{
47
48
  readonly type: "uint256";
48
49
  }];
50
+ }, {
51
+ readonly name: "pairedToken";
52
+ readonly type: "function";
53
+ readonly stateMutability: "view";
54
+ readonly inputs: readonly [{
55
+ readonly type: "bytes32";
56
+ readonly name: "_poolId";
57
+ }];
58
+ readonly outputs: readonly [{
59
+ readonly type: "address";
60
+ }];
49
61
  }];
50
62
  export declare const spendGatedAbi: readonly [{
51
63
  readonly name: "spendGateSettings";
@@ -60,7 +72,7 @@ export declare const spendGatedAbi: readonly [{
60
72
  readonly name: "enabled";
61
73
  }, {
62
74
  readonly type: "uint256";
63
- readonly name: "walletCapWei";
75
+ readonly name: "walletCap";
64
76
  }, {
65
77
  readonly type: "address";
66
78
  readonly name: "settler";
@@ -99,11 +111,17 @@ export interface Launch {
99
111
  opensAt: number;
100
112
  /** When the gate stops enforcing on chain, in epoch ms. */
101
113
  closesAt: number;
102
- walletCapWei: bigint;
114
+ /** In base units of `spendToken`. */
115
+ walletCap: bigint;
103
116
  signer: `0x${string}`;
104
117
  name: string;
105
118
  symbol: string;
106
119
  imageUrl?: string | null;
120
+ /**
121
+ * The token spend is measured in: the coin's paired token, read from the manager. Absent only
122
+ * from hand-built launches (demos, tests), where it means ETH.
123
+ */
124
+ spendToken?: SpendToken;
107
125
  }
108
126
  /**
109
127
  * A refusal, with the one distinction that matters.
@@ -1 +1 @@
1
- {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/chain/discover.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AAEnF;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;AAuB7D,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUrB,CAAC;AAEX,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKxB,CAAC;AAIH,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;IACzB,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,KAAK,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;IAC3B,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,WAAW,GAAG,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC;AAE5D,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,KAAK,MAAM,EAAE,CAAC;IAC/B,oBAAoB,EAAE,KAAK,MAAM,EAAE,CAAC;IACpC,kFAAkF;IAClF,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;CACvB;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,MAAM,EAAE,CAOpD;AAID;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,KAAK,MAAM,EAAE,GACtB,OAAO,CAAC,WAAW,CAAC,CA2EtB;AAED;;;;;;;;;GASG;AACH,qBAAa,SAAS;IAKlB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8D;IACvF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2C;gBAGjD,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,UAAU,EACtB,GAAG,GAAE,MAAM,MAAiB;IAGzC,MAAM,CAAC,QAAQ,EAAE,KAAK,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAqB3D,OAAO,CAAC,OAAO;CAIhB"}
1
+ {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/chain/discover.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AACnF,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;AA6B7D,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAerB,CAAC;AAEX,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKxB,CAAC;AAUH,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;IACzB,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,KAAK,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;IAC3B,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,WAAW,GAAG,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC;AAE5D,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,KAAK,MAAM,EAAE,CAAC;IAC/B,oBAAoB,EAAE,KAAK,MAAM,EAAE,CAAC;IACpC,kFAAkF;IAClF,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;CACvB;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,MAAM,EAAE,CAOpD;AAID;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,KAAK,MAAM,EAAE,GACtB,OAAO,CAAC,WAAW,CAAC,CA0FtB;AA2CD;;;;;;;;;GASG;AACH,qBAAa,SAAS;IAKlB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8D;IACvF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2C;gBAGjD,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,UAAU,EACtB,GAAG,GAAE,MAAM,MAAiB;IAGzC,MAAM,CAAC,QAAQ,EAAE,KAAK,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAqB3D,OAAO,CAAC,OAAO;CAIhB"}
@@ -1,4 +1,5 @@
1
1
  import { encodeAbiParameters, keccak256, parseAbi } from 'viem';
2
+ import { ETH_SPEND_TOKEN } from '@flayerlabs/gamemode-spec/live';
2
3
  /**
3
4
  * Asking the chain whether a coin is really a game launch, and on what terms.
4
5
  *
@@ -10,6 +11,12 @@ import { encodeAbiParameters, keccak256, parseAbi } from 'viem';
10
11
  * launch's own gate parameters, and that is public state the creator paid to write and nobody else
11
12
  * can forge. So adoption needs no API key and no allowlist — anyone may ask, and the chain decides.
12
13
  * That single property is what makes third-party games permissionless.
14
+ *
15
+ * A gate serves exactly one (PositionManager, calculator) pair and adopts only coins launched on
16
+ * THAT manager: `poolKey(coin)` is asked of the configured manager alone, so a coin on a superseded
17
+ * generation of hooks (which keeps trading on its own gate) reads back as not a launch here. That
18
+ * is deliberate — the EIP-712 domain binds every authorisation to the calculator, so a coin this
19
+ * gate cannot sign for must not be given a room by it.
13
20
  */
14
21
  const poolKeyComponents = [
15
22
  { name: 'currency0', type: 'address' },
@@ -27,15 +34,25 @@ export const positionManagerAbi = [
27
34
  outputs: [{ name: '', type: 'tuple', components: poolKeyComponents }],
28
35
  },
29
36
  // The scheduled open of the buy window; 0 once the pool is tradeable.
30
- ...parseAbi(['function flaunchesAt(bytes32 _poolId) view returns (uint256)']),
37
+ ...parseAbi([
38
+ 'function flaunchesAt(bytes32 _poolId) view returns (uint256)',
39
+ // V1_3 only: the token the pool is paired with. A legacy manager has no such function; a revert
40
+ // there is read as "flETH", which is the only pairing that generation can produce.
41
+ 'function pairedToken(bytes32 _poolId) view returns (address)',
42
+ ]),
31
43
  ];
32
44
  export const spendGatedAbi = parseAbi([
33
45
  // Four fields. Decoding a four-word return against a shorter ABI is how a check quietly reads the
34
46
  // wrong value, so this must match the DEPLOYED calculator rather than the newest source.
35
- 'function spendGateSettings(bytes32 _poolId) view returns (bool enabled, uint256 walletCapWei, address settler, uint256 endsAt)',
47
+ 'function spendGateSettings(bytes32 _poolId) view returns (bool enabled, uint256 walletCap, address settler, uint256 endsAt)',
36
48
  'function trustedPoolKeySigner(bytes32 _poolId) view returns (address signer, bool enabled)',
37
49
  ]);
38
- const erc20 = parseAbi(['function name() view returns (string)', 'function symbol() view returns (string)']);
50
+ const erc20 = parseAbi([
51
+ 'function name() view returns (string)',
52
+ 'function symbol() view returns (string)',
53
+ 'function decimals() view returns (uint8)',
54
+ ]);
55
+ const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
39
56
  export function poolIdOf(key) {
40
57
  return keccak256(encodeAbiParameters([{ type: 'address' }, { type: 'address' }, { type: 'uint24' }, { type: 'int24' }, { type: 'address' }], [key.currency0, key.currency1, key.fee, key.tickSpacing, key.hooks]));
41
58
  }
@@ -92,7 +109,7 @@ export async function verifyLaunch(client, deployment, memecoin) {
92
109
  catch {
93
110
  return refuse('launch.unreadable', true);
94
111
  }
95
- const [enabled, walletCapWei, , endsAt] = settings;
112
+ const [enabled, walletCap, , endsAt] = settings;
96
113
  const [signer, signerEnabled] = trusted;
97
114
  if (!enabled)
98
115
  return refuse('launch.not_a_game', false);
@@ -100,12 +117,15 @@ export async function verifyLaunch(client, deployment, memecoin) {
100
117
  if (!signerEnabled || signer.toLowerCase() !== deployment.signer.toLowerCase()) {
101
118
  return refuse('launch.another_signer', false);
102
119
  }
103
- if (walletCapWei <= 0n)
120
+ if (walletCap <= 0n)
104
121
  return refuse('launch.no_spending_cap', false);
105
122
  const opensAt = Number(flaunchesAt) * 1000;
106
123
  const closesAt = Number(endsAt) * 1000;
107
124
  if (closesAt <= Date.now())
108
125
  return refuse('launch.already_over', false);
126
+ const spendToken = await resolveSpendToken(client, deployment, memecoin, poolKey, poolId);
127
+ if (!spendToken)
128
+ return refuse('launch.paired_unreadable', true);
109
129
  let name = '';
110
130
  let symbol = '';
111
131
  try {
@@ -118,7 +138,55 @@ export async function verifyLaunch(client, deployment, memecoin) {
118
138
  // Cosmetic. A coin with an unreadable name is still a valid launch, and refusing one over a
119
139
  // display string would be refusing a round for no reason anyone could act on.
120
140
  }
121
- return { ok: true, coinAddress: memecoin, poolId, poolKey, opensAt, closesAt, walletCapWei, signer, name, symbol };
141
+ return {
142
+ ok: true,
143
+ coinAddress: memecoin,
144
+ poolId,
145
+ poolKey,
146
+ opensAt,
147
+ closesAt,
148
+ walletCap,
149
+ signer,
150
+ name,
151
+ symbol,
152
+ spendToken,
153
+ };
154
+ }
155
+ /**
156
+ * Which token this pool's spend is measured in.
157
+ *
158
+ * The calculator measures spend on the pool's PAIRED side, so the gate's cap and allocations must
159
+ * be in that token's base units — a six-decimal stablecoin priced as if it were wei authorises a
160
+ * trillion times too much. Asked of the manager first (`pairedToken`, V1_3), and derived from the
161
+ * pool key when the manager predates the function: the key names two currencies and one of them
162
+ * is the coin. Decimals are load-bearing, so unlike the coin's cosmetic name an unreadable token
163
+ * is a refusal — retryable, because an RPC blip is not a statement about the token.
164
+ */
165
+ async function resolveSpendToken(client, deployment, memecoin, poolKey, poolId) {
166
+ let paired;
167
+ try {
168
+ paired = (await client.readContract({
169
+ address: deployment.positionManager,
170
+ abi: positionManagerAbi,
171
+ functionName: 'pairedToken',
172
+ args: [poolId],
173
+ }));
174
+ }
175
+ catch {
176
+ paired = poolKey.currency0.toLowerCase() === memecoin.toLowerCase() ? poolKey.currency1 : poolKey.currency0;
177
+ }
178
+ if (paired.toLowerCase() === ZERO_ADDRESS)
179
+ return ETH_SPEND_TOKEN;
180
+ try {
181
+ const [symbol, decimals] = (await Promise.all([
182
+ client.readContract({ address: paired, abi: erc20, functionName: 'symbol' }),
183
+ client.readContract({ address: paired, abi: erc20, functionName: 'decimals' }),
184
+ ]));
185
+ return { address: paired, symbol, decimals: Number(decimals), isNative: false };
186
+ }
187
+ catch {
188
+ return null;
189
+ }
122
190
  }
123
191
  /**
124
192
  * Verification with a memory, because every coin-page view asks.
@@ -1 +1 @@
1
- {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/chain/discover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,QAAQ,EAAqB,MAAM,MAAM,CAAC;AAWnF;;;;;;;;;;;GAWG;AAEH,MAAM,iBAAiB,GAAG;IACxB,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE;IACtC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE;IACtC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC/B,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE;IACtC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;CAC1B,CAAC;AAEX,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,SAAS;QACf,eAAe,EAAE,MAAM;QACvB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7C,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC;KACtE;IACD,sEAAsE;IACtE,GAAG,QAAQ,CAAC,CAAC,8DAA8D,CAAC,CAAC;CACrE,CAAC;AAEX,MAAM,CAAC,MAAM,aAAa,GAAG,QAAQ,CAAC;IACpC,kGAAkG;IAClG,yFAAyF;IACzF,gIAAgI;IAChI,4FAA4F;CAC7F,CAAC,CAAC;AAEH,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,uCAAuC,EAAE,yCAAyC,CAAC,CAAC,CAAC;AAgD7G,MAAM,UAAU,QAAQ,CAAC,GAAY;IACnC,OAAO,SAAS,CACd,mBAAmB,CACjB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EACtG,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,KAAK,CAAC,CACpE,CACF,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,SAAkB,EAAW,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAE/F;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAmB,EACnB,UAAsB,EACtB,QAAuB;IAEvB,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC;YACnC,OAAO,EAAE,UAAU,CAAC,eAAe;YACnC,GAAG,EAAE,kBAAkB;YACvB,YAAY,EAAE,SAAS;YACvB,IAAI,EAAE,CAAC,QAAQ,CAAC;SACjB,CAAC,CAAY,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,oFAAoF;IACpF,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,KAAK,4CAA4C,EAAE,CAAC;QAC/E,OAAO,MAAM,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEjC,IAAI,QAA2D,CAAC;IAChE,IAAI,OAA0C,CAAC;IAC/C,IAAI,WAAmB,CAAC;IACxB,IAAI,CAAC;QACH,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC;YACpD,MAAM,CAAC,YAAY,CAAC;gBAClB,OAAO,EAAE,UAAU,CAAC,oBAAoB;gBACxC,GAAG,EAAE,aAAa;gBAClB,YAAY,EAAE,mBAAmB;gBACjC,IAAI,EAAE,CAAC,MAAM,CAAC;aACf,CAAC;YACF,MAAM,CAAC,YAAY,CAAC;gBAClB,OAAO,EAAE,UAAU,CAAC,oBAAoB;gBACxC,GAAG,EAAE,aAAa;gBAClB,YAAY,EAAE,sBAAsB;gBACpC,IAAI,EAAE,CAAC,MAAM,CAAC;aACf,CAAC;YACF,MAAM,CAAC,YAAY,CAAC;gBAClB,OAAO,EAAE,UAAU,CAAC,eAAe;gBACnC,GAAG,EAAE,kBAAkB;gBACvB,YAAY,EAAE,aAAa;gBAC3B,IAAI,EAAE,CAAC,MAAM,CAAC;aACf,CAAC;SACH,CAAC,CAA8C,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,OAAO,EAAE,YAAY,EAAE,AAAD,EAAG,MAAM,CAAC,GAAG,QAAQ,CAAC;IACnD,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,OAAO,CAAC;IAExC,IAAI,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;IACxD,gGAAgG;IAChG,IAAI,CAAC,aAAa,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QAC/E,OAAO,MAAM,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,YAAY,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;IAEvE,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACvC,IAAI,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,MAAM,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAExE,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,CAAC;QACH,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC;YAClC,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;YAC5E,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;SAC/E,CAAC,CAAqB,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,4FAA4F;QAC5F,8EAA8E;IAChF,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACrH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,OAAO,SAAS;IAKD;IACA;IACA;IANF,QAAQ,GAAG,IAAI,GAAG,EAAmD,CAAC;IACtE,QAAQ,GAAG,IAAI,GAAG,EAAgC,CAAC;IAEpE,YACmB,MAAmB,EACnB,UAAsB,EACtB,MAAoB,IAAI,CAAC,GAAG;QAF5B,WAAM,GAAN,MAAM,CAAa;QACnB,eAAU,GAAV,UAAU,CAAY;QACtB,QAAG,GAAH,GAAG,CAAyB;IAC5C,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,QAAuB;QAClC,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;YAAE,OAAO,MAAM,CAAC,OAAO,CAAC;QAE/D,uFAAuF;QACvF,sFAAsF;QACtF,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAE9B,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC;aAChE,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;YAChB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC/E,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAE5C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,OAAO,CAAC,OAAoB;QAClC,IAAI,OAAO,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAClE,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5C,CAAC;CACF"}
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/chain/discover.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,21 @@
1
- import type { PublicClient } from 'viem';
1
+ import { type PublicClient } from 'viem';
2
+ import type { FlaunchVariant } from './chains.js';
2
3
  /** The demo's session-secret fallback, which every copy of this repo shares. */
3
4
  export declare const DEMO_SESSION_SECRET = "dev-secret-that-is-long-enough-to-pass";
5
+ /** `ProtocolRoles.POSITION_MANAGER` in flaunch-contracts: the role a calculator demands of its caller. */
6
+ export declare const POSITION_MANAGER_ROLE: `0x${string}`;
4
7
  export interface SecureConfig {
5
8
  chainId: number;
6
9
  signerPrivateKey: string;
7
10
  spendGatedCalculator: `0x${string}`;
8
11
  sessionSecret: string;
12
+ /**
13
+ * When given, the wiring between the manager and the calculator is read back and asserted — see
14
+ * {@link assertWiring}. Optional so a caller that only wants the key and chain checks keeps them.
15
+ */
16
+ positionManager?: `0x${string}`;
17
+ flaunchVariant?: FlaunchVariant;
18
+ poolSwap?: `0x${string}`;
9
19
  }
10
20
  export declare function assertSecureConfig(client: PublicClient, config: SecureConfig): Promise<void>;
11
21
  //# sourceMappingURL=secure.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"secure.d.ts","sourceRoot":"","sources":["../../src/chain/secure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAezC,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,2CAA2C,CAAC;AAE5E,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,KAAK,MAAM,EAAE,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBlG"}
1
+ {"version":3,"file":"secure.d.ts","sourceRoot":"","sources":["../../src/chain/secure.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAelD,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,2CAA2C,CAAC;AAE5E,0GAA0G;AAC1G,eAAO,MAAM,qBAAqB,eAAsC,CAAC;AASzE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,KAAK,MAAM,EAAE,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,eAAe,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBlG"}
@@ -1,3 +1,4 @@
1
+ import { keccak256, parseAbi, toHex } from 'viem';
1
2
  /**
2
3
  * The boot-time refusals {@link PayloadSigner}'s doc comment promises.
3
4
  *
@@ -11,6 +12,14 @@ const DEMO_SIGNING_KEY = `0x${'11'.repeat(32)}`;
11
12
  const ZERO_KEY = `0x${'00'.repeat(32)}`;
12
13
  /** The demo's session-secret fallback, which every copy of this repo shares. */
13
14
  export const DEMO_SESSION_SECRET = 'dev-secret-that-is-long-enough-to-pass';
15
+ /** `ProtocolRoles.POSITION_MANAGER` in flaunch-contracts: the role a calculator demands of its caller. */
16
+ export const POSITION_MANAGER_ROLE = keccak256(toHex('PositionManager'));
17
+ const wiringAbi = parseAbi([
18
+ 'function feeCalculator() view returns (address)',
19
+ 'function registeredCalculators(address) view returns (bool)',
20
+ 'function hasRole(bytes32 role, address account) view returns (bool)',
21
+ 'function approvedRouters(address) view returns (bool)',
22
+ ]);
14
23
  export async function assertSecureConfig(client, config) {
15
24
  const key = config.signerPrivateKey.toLowerCase();
16
25
  if (key === DEMO_SIGNING_KEY || key === ZERO_KEY) {
@@ -32,5 +41,63 @@ export async function assertSecureConfig(client, config) {
32
41
  if (!code || code === '0x') {
33
42
  throw new Error(`SPEND_GATED_CALCULATOR ${config.spendGatedCalculator} holds no code on chain ${chainId}`);
34
43
  }
44
+ if (config.positionManager)
45
+ await assertWiring(client, config);
46
+ }
47
+ /**
48
+ * The manager must route fees through a dispatcher that knows this calculator, and the calculator
49
+ * must accept calls from that dispatcher. Both are one-time owner actions on chain, and a stack
50
+ * missing either ADOPTS launches whose swaps never reach the gate: the pool trades ungated while
51
+ * the gate believes it is enforcing a cap. That is the whole failure this function refuses.
52
+ *
53
+ * A paired stack additionally needs its PoolSwap approved as a router, because a paired buy arrives
54
+ * through it and the calculator binds a smart wallet's buyer identity to an approved router's
55
+ * `msgSender()` — unapproved, every such buy reverts at the swap.
56
+ */
57
+ async function assertWiring(client, config) {
58
+ const manager = config.positionManager;
59
+ const calculator = config.spendGatedCalculator;
60
+ let dispatcher;
61
+ try {
62
+ dispatcher = await client.readContract({ address: manager, abi: wiringAbi, functionName: 'feeCalculator' });
63
+ }
64
+ catch {
65
+ throw new Error(`POSITION_MANAGER ${manager} does not answer feeCalculator() — is it a Flaunch PositionManager?`);
66
+ }
67
+ const [registered, hasRole] = await Promise.all([
68
+ client.readContract({
69
+ address: dispatcher,
70
+ abi: wiringAbi,
71
+ functionName: 'registeredCalculators',
72
+ args: [calculator],
73
+ }).catch(() => false),
74
+ client.readContract({
75
+ address: calculator,
76
+ abi: wiringAbi,
77
+ functionName: 'hasRole',
78
+ args: [POSITION_MANAGER_ROLE, dispatcher],
79
+ }).catch(() => false),
80
+ ]);
81
+ if (!registered) {
82
+ throw new Error(`the fee dispatcher ${dispatcher} of POSITION_MANAGER ${manager} does not have SPEND_GATED_CALCULATOR ` +
83
+ `${calculator} registered — its owner must call setCalculatorRegistered(${calculator}, true) before ` +
84
+ 'this gate can serve launches on that manager');
85
+ }
86
+ if (!hasRole) {
87
+ throw new Error(`SPEND_GATED_CALCULATOR ${calculator} has not granted the PositionManager role to the dispatcher ${dispatcher} ` +
88
+ `— its admin must call grantRole(${POSITION_MANAGER_ROLE}, ${dispatcher})`);
89
+ }
90
+ if (config.flaunchVariant === 'v1_3') {
91
+ if (!config.poolSwap) {
92
+ throw new Error('a v1_3 stack needs POOL_SWAP — the router a paired-token buy goes through');
93
+ }
94
+ const approved = await client
95
+ .readContract({ address: calculator, abi: wiringAbi, functionName: 'approvedRouters', args: [config.poolSwap] })
96
+ .catch(() => false);
97
+ if (!approved) {
98
+ throw new Error(`SPEND_GATED_CALCULATOR ${calculator} has not approved POOL_SWAP ${config.poolSwap} as a router — ` +
99
+ `its owner must call setApprovedRouter(${config.poolSwap}, true)`);
100
+ }
101
+ }
35
102
  }
36
103
  //# sourceMappingURL=secure.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"secure.js","sourceRoot":"","sources":["../../src/chain/secure.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,mGAAmG;AACnG,MAAM,gBAAgB,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;AAChD,MAAM,QAAQ,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;AAExC,gFAAgF;AAChF,MAAM,CAAC,MAAM,mBAAmB,GAAG,wCAAwC,CAAC;AAS5E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAoB,EAAE,MAAoB;IACjF,MAAM,GAAG,GAAG,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC;IAClD,IAAI,GAAG,KAAK,gBAAgB,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC7F,CAAC;IACD,IAAI,MAAM,CAAC,aAAa,KAAK,mBAAmB,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IAED,gGAAgG;IAChG,gGAAgG;IAChG,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC1C,IAAI,OAAO,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,qBAAqB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,+FAA+F;IAC/F,4FAA4F;IAC5F,mBAAmB;IACnB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAC5E,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,CAAC,oBAAoB,2BAA2B,OAAO,EAAE,CAAC,CAAC;IAC7G,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"secure.js","sourceRoot":"","sources":["../../src/chain/secure.ts"],"names":[],"mappings":"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"}
package/dist/claims.d.ts CHANGED
@@ -55,7 +55,7 @@ export declare class Claims {
55
55
  /** Give back every authorisation that expired unspent. */
56
56
  releaseExpired(): Promise<BalanceKey[]>;
57
57
  /** What this player could spend right now. */
58
- availableWei(roundId: string, player: PlayerId): Promise<bigint>;
58
+ available(roundId: string, player: PlayerId): Promise<bigint>;
59
59
  /** Full authoritative balance for live snapshots. */
60
60
  economyBalance(roundId: string, player: PlayerId): Promise<EconomyBalance>;
61
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"claims.d.ts","sourceRoot":"","sources":["../src/claims.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAc,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEtE;;;;;;;;;;;GAWG;AAEH;mDACmD;AACnD,eAAO,MAAM,0BAA0B,QAAa,CAAC;AAIrD,sGAAsG;AACtG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEhE;AAED,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE7D;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC,qBAAa,MAAM;IAEf,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,kFAAkF;IAClF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAChC,2FAA2F;IAC3F,OAAO,CAAC,QAAQ,CAAC,GAAG;gBANH,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa;IACtC,kFAAkF;IACjE,cAAc,CAAC,GAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,aAAA;IACzE,2FAA2F;IAC1E,GAAG,GAAE,MAAM,MAAiB;IAG/C;;;;;;;OAOG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAyBhG,MAAM;IA4BpB,0DAA0D;IAC1D,cAAc,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAIvC,8CAA8C;IAC9C,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAIhE,qDAAqD;IACrD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC;CAG3E"}
1
+ {"version":3,"file":"claims.d.ts","sourceRoot":"","sources":["../src/claims.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAc,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEtE;;;;;;;;;;;GAWG;AAEH;mDACmD;AACnD,eAAO,MAAM,0BAA0B,QAAa,CAAC;AAIrD,sGAAsG;AACtG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEhE;AAED,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE7D;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC,qBAAa,MAAM;IAEf,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,kFAAkF;IAClF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAChC,2FAA2F;IAC3F,OAAO,CAAC,QAAQ,CAAC,GAAG;gBANH,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa;IACtC,kFAAkF;IACjE,cAAc,CAAC,GAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,aAAA;IACzE,2FAA2F;IAC1E,GAAG,GAAE,MAAM,MAAiB;IAG/C;;;;;;;OAOG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAyBhG,MAAM;IA4BpB,0DAA0D;IAC1D,cAAc,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAIvC,8CAA8C;IAC9C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7D,qDAAqD;IACrD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC;CAG3E"}
package/dist/claims.js CHANGED
@@ -104,8 +104,8 @@ export class Claims {
104
104
  return this.ledger.releaseExpired(Math.floor(this.now() / 1000));
105
105
  }
106
106
  /** What this player could spend right now. */
107
- availableWei(roundId, player) {
108
- return this.ledger.availableWei(roundId, player);
107
+ available(roundId, player) {
108
+ return this.ledger.available(roundId, player);
109
109
  }
110
110
  /** Full authoritative balance for live snapshots. */
111
111
  economyBalance(roundId, player) {