@flayerlabs/gamemode-gate 0.4.3 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEPLOY.md +27 -3
- package/README.md +8 -3
- package/dist/chain/chains.d.ts +45 -6
- package/dist/chain/chains.d.ts.map +1 -1
- package/dist/chain/chains.js +56 -5
- package/dist/chain/chains.js.map +1 -1
- package/dist/chain/discover.d.ts +20 -2
- package/dist/chain/discover.d.ts.map +1 -1
- package/dist/chain/discover.js +74 -6
- package/dist/chain/discover.js.map +1 -1
- package/dist/chain/secure.d.ts +11 -1
- package/dist/chain/secure.d.ts.map +1 -1
- package/dist/chain/secure.js +67 -0
- package/dist/chain/secure.js.map +1 -1
- package/dist/claims.d.ts +1 -1
- package/dist/claims.d.ts.map +1 -1
- package/dist/claims.js +2 -2
- package/dist/claims.js.map +1 -1
- package/dist/demo.d.ts +1 -1
- package/dist/demo.d.ts.map +1 -1
- package/dist/demo.js +9 -9
- package/dist/demo.js.map +1 -1
- package/dist/economy.d.ts +25 -9
- package/dist/economy.d.ts.map +1 -1
- package/dist/economy.js +63 -22
- package/dist/economy.js.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/ledger.d.ts +2 -2
- package/dist/ledger.d.ts.map +1 -1
- package/dist/ledger.js +16 -16
- package/dist/ledger.js.map +1 -1
- package/dist/main.d.ts +30 -5
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +158 -17
- package/dist/main.js.map +1 -1
- package/dist/room.d.ts +7 -4
- package/dist/room.d.ts.map +1 -1
- package/dist/room.js +31 -10
- package/dist/room.js.map +1 -1
- package/dist/server.d.ts +33 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +93 -25
- package/dist/server.js.map +1 -1
- package/dist/standings.d.ts +34 -0
- package/dist/standings.d.ts.map +1 -0
- package/dist/standings.js +103 -0
- package/dist/standings.js.map +1 -0
- package/dist/store.d.ts +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +21 -0
- package/dist/store.js.map +1 -1
- package/package.json +2 -2
- package/src/chain/chains.ts +82 -9
- package/src/chain/discover.ts +87 -7
- package/src/chain/secure.ts +86 -1
- package/src/claims.ts +2 -2
- package/src/demo.ts +10 -10
- package/src/economy.ts +83 -31
- package/src/index.ts +8 -5
- package/src/ledger.ts +18 -18
- package/src/main.ts +181 -19
- package/src/room.ts +41 -14
- package/src/server.ts +142 -35
- package/src/standings.ts +138 -0
- 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 |
|
|
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;
|
|
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
|
-
|
|
119
|
+
walletCap: '25000000000000000',
|
|
120
120
|
roundDurationMs: 90_000,
|
|
121
121
|
minLobbyLeadMs: 60_000,
|
|
122
122
|
gateEndsAtGraceS: 10,
|
|
123
|
-
flaunchVariant: '
|
|
123
|
+
flaunchVariant: 'v1_2',
|
|
124
124
|
requiresEoa: false,
|
|
125
125
|
accepting: true,
|
|
126
126
|
publicLaunchesOpen: true,
|
|
@@ -170,6 +170,11 @@ retries safe.
|
|
|
170
170
|
may earn, so your server can refuse a seat before the player takes one. That read is advisory; the
|
|
171
171
|
award route still enforces the ceiling.
|
|
172
172
|
|
|
173
|
+
Every gate also serves two public reads the Flaunch coin page renders: `GET /coins/:coin/rankings`,
|
|
174
|
+
the round's standings once it is over (and the running order while it is live), and a `roster` on
|
|
175
|
+
`GET /rounds/:id` naming who holds a seat. Nothing to configure — see
|
|
176
|
+
[read the standings](https://github.com/flayerlabs/gamemode-sdk/blob/main/docs/guides/run-a-gate.md#read-the-standings).
|
|
177
|
+
|
|
173
178
|
Use the [external game-server steps](https://github.com/flayerlabs/gamemode-sdk/blob/main/docs/guides/run-a-gate.md#connect-an-existing-game-server)
|
|
174
179
|
for the request format, responses and deployment checks. The
|
|
175
180
|
[runnable external-server example](https://github.com/flayerlabs/gamemode-sdk/tree/main/examples/external-server)
|
package/dist/chain/chains.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
22
|
-
*
|
|
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
|
-
|
|
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
|
-
/**
|
|
29
|
-
|
|
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
|
|
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"}
|
package/dist/chain/chains.js
CHANGED
|
@@ -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: '
|
|
32
|
+
flaunchVariant: 'v1_2',
|
|
33
|
+
fleth: '0x79FC52701cD4BE6f9Ba9aDC94c207DE37e3314eb',
|
|
27
34
|
},
|
|
28
35
|
};
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
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
|
package/dist/chain/chains.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chains.js","sourceRoot":"","sources":["../../src/chain/chains.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|
package/dist/chain/discover.d.ts
CHANGED
|
@@ -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: "
|
|
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
|
-
|
|
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;
|
|
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"}
|
package/dist/chain/discover.js
CHANGED
|
@@ -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([
|
|
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
|
|
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([
|
|
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,
|
|
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 (
|
|
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 {
|
|
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;
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/chain/discover.ts"],"names":[],"mappings":"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"}
|
package/dist/chain/secure.d.ts
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import type
|
|
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,
|
|
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"}
|
package/dist/chain/secure.js
CHANGED
|
@@ -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
|
package/dist/chain/secure.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secure.js","sourceRoot":"","sources":["../../src/chain/secure.ts"],"names":[],"mappings":"
|
|
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
|
-
|
|
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
|
}
|
package/dist/claims.d.ts.map
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
108
|
-
return this.ledger.
|
|
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) {
|