@floorlaunchpad/sdk-evm 0.0.0-stage → 0.1.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.
- package/LICENSE +61 -0
- package/README.md +154 -2
- package/dist/abi/floor.d.ts +1315 -0
- package/dist/abi/floor.d.ts.map +1 -0
- package/dist/abi/floor.js +154 -0
- package/dist/abi/floor.js.map +1 -0
- package/dist/abi/generated.d.ts +12824 -0
- package/dist/abi/generated.d.ts.map +1 -0
- package/dist/abi/generated.js +1264 -0
- package/dist/abi/generated.js.map +1 -0
- package/dist/abi/index.d.ts +2 -0
- package/dist/abi/index.d.ts.map +1 -0
- package/dist/abi/index.js +2 -0
- package/dist/abi/index.js.map +1 -0
- package/dist/adapter.d.ts +89 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +250 -0
- package/dist/adapter.js.map +1 -0
- package/dist/deployments.d.ts +154 -0
- package/dist/deployments.d.ts.map +1 -0
- package/dist/deployments.js +368 -0
- package/dist/deployments.js.map +1 -0
- package/dist/errors.d.ts +56 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +42 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +45 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +78 -0
- package/dist/events.js.map +1 -0
- package/dist/fees.d.ts +100 -0
- package/dist/fees.d.ts.map +1 -0
- package/dist/fees.js +156 -0
- package/dist/fees.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/pool.d.ts +63 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/pool.js +118 -0
- package/dist/pool.js.map +1 -0
- package/dist/reads.d.ts +107 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +201 -0
- package/dist/reads.js.map +1 -0
- package/dist/router.d.ts +99 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +132 -0
- package/dist/router.js.map +1 -0
- package/dist/sale.d.ts +79 -0
- package/dist/sale.d.ts.map +1 -0
- package/dist/sale.js +123 -0
- package/dist/sale.js.map +1 -0
- package/dist/send.d.ts +64 -0
- package/dist/send.d.ts.map +1 -0
- package/dist/send.js +137 -0
- package/dist/send.js.map +1 -0
- package/dist/simulate.d.ts +180 -0
- package/dist/simulate.d.ts.map +1 -0
- package/dist/simulate.js +270 -0
- package/dist/simulate.js.map +1 -0
- package/dist/trade.d.ts +140 -0
- package/dist/trade.d.ts.map +1 -0
- package/dist/trade.js +170 -0
- package/dist/trade.js.map +1 -0
- package/package.json +43 -4
package/dist/sale.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { MalformedSale } from './errors.js';
|
|
2
|
+
import { MAX_SALE_TEAM_FEE_BPS, saleGrossFor, saleNetOf, teamFeeOf } from './fees.js';
|
|
3
|
+
export const MAX_TRANCHES = 255;
|
|
4
|
+
export function validTranches(n) {
|
|
5
|
+
return typeof n === 'number' && Number.isInteger(n) && n >= 1 && n <= MAX_TRANCHES;
|
|
6
|
+
}
|
|
7
|
+
/** The getters' answers, checked: tranches in 1..255, the fee a rate under the sale's cap. Throws `MalformedSale`. */
|
|
8
|
+
export function saleReadsFrom(raw) {
|
|
9
|
+
const t = raw.tranches;
|
|
10
|
+
const tranches = typeof t === 'bigint' ? (t >= 1n && t <= BigInt(MAX_TRANCHES) ? Number(t) : NaN) : t;
|
|
11
|
+
if (!validTranches(tranches))
|
|
12
|
+
throw new MalformedSale(`tranches() returned ${String(t)}, outside 1..${MAX_TRANCHES}`);
|
|
13
|
+
if (!Number.isInteger(raw.teamFeeBps) || raw.teamFeeBps < 0)
|
|
14
|
+
throw new MalformedSale(`teamFeeBps ${String(raw.teamFeeBps)} is not a rate`);
|
|
15
|
+
if (raw.teamFeeBps > MAX_SALE_TEAM_FEE_BPS)
|
|
16
|
+
throw new MalformedSale(`teamFeeBps ${raw.teamFeeBps} is above the sale's cap ${MAX_SALE_TEAM_FEE_BPS} — refused, never walked`);
|
|
17
|
+
return { ...raw, tranches };
|
|
18
|
+
}
|
|
19
|
+
export function trancheSize(s) {
|
|
20
|
+
return validTranches(s.tranches) ? s.saleTokens / BigInt(s.tranches) : 0n;
|
|
21
|
+
}
|
|
22
|
+
/** Tranche `i`'s price: raw quote per WHOLE (1e18-unit) token, linear from `p0` to `p1`. */
|
|
23
|
+
export function tranchePrice(s, i) {
|
|
24
|
+
if (!validTranches(s.tranches) || s.tranches === 1)
|
|
25
|
+
return s.p0;
|
|
26
|
+
return s.p0 + ((s.p1 - s.p0) * BigInt(i)) / BigInt(s.tranches - 1);
|
|
27
|
+
}
|
|
28
|
+
export function currentTranche(s) {
|
|
29
|
+
const size = trancheSize(s);
|
|
30
|
+
if (size === 0n)
|
|
31
|
+
return 0;
|
|
32
|
+
return Math.min(Number(s.sold / size), Math.max(s.tranches - 1, 0));
|
|
33
|
+
}
|
|
34
|
+
/** A tranche slice's cost: `tokens × price / unit`, rounded as `rounding` says. */
|
|
35
|
+
export function trancheCost(tokens, price, unit, rounding) {
|
|
36
|
+
const n = tokens * price;
|
|
37
|
+
return rounding === 'ceil' ? (n + unit - 1n) / unit : n / unit;
|
|
38
|
+
}
|
|
39
|
+
/** The whole raise: what buying every sale token costs (before the FLOOR Platform fee). */
|
|
40
|
+
export function saleTargetWei(s, rounding = 'ceil') {
|
|
41
|
+
if (!validTranches(s.tranches))
|
|
42
|
+
return 0n;
|
|
43
|
+
const size = trancheSize(s);
|
|
44
|
+
if (size === 0n)
|
|
45
|
+
return 0n;
|
|
46
|
+
const E18 = 10n ** 18n;
|
|
47
|
+
let total = 0n;
|
|
48
|
+
for (let t = 0; t < s.tranches; t++) {
|
|
49
|
+
const end = t === s.tranches - 1 ? s.saleTokens : BigInt(t + 1) * size;
|
|
50
|
+
total += trancheCost(end - BigInt(t) * size, tranchePrice(s, t), E18, rounding);
|
|
51
|
+
}
|
|
52
|
+
return total;
|
|
53
|
+
}
|
|
54
|
+
const UINT256_MAX = (1n << 256n) - 1n;
|
|
55
|
+
/** `FloorLaunch._walk(budget)`: tokens received and quote spent, from the book's current `sold`. */
|
|
56
|
+
function walkBuy(s, amountIn, unit, rounding) {
|
|
57
|
+
const size = trancheSize(s);
|
|
58
|
+
if (size === 0n || amountIn <= 0n)
|
|
59
|
+
return { got: 0n, spent: 0n };
|
|
60
|
+
const costOf = (tokens, price) => trancheCost(tokens, price, unit, rounding);
|
|
61
|
+
let sold = s.sold, left = amountIn, got = 0n;
|
|
62
|
+
while (left > 0n && sold < s.saleTokens) {
|
|
63
|
+
const t = Math.min(Number(sold / size), s.tranches - 1);
|
|
64
|
+
const end = t === s.tranches - 1 ? s.saleTokens : BigInt(t + 1) * size;
|
|
65
|
+
const capacity = end - sold;
|
|
66
|
+
const price = tranchePrice(s, t);
|
|
67
|
+
const costAll = costOf(capacity, price);
|
|
68
|
+
if (left >= costAll && costAll > 0n) {
|
|
69
|
+
sold += capacity;
|
|
70
|
+
got += capacity;
|
|
71
|
+
left -= costAll;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
if (price === 0n)
|
|
75
|
+
break;
|
|
76
|
+
let amt = (left * unit) / price;
|
|
77
|
+
if (amt === 0n)
|
|
78
|
+
break;
|
|
79
|
+
if (amt > capacity)
|
|
80
|
+
amt = capacity;
|
|
81
|
+
const cost = costOf(amt, price);
|
|
82
|
+
sold += amt;
|
|
83
|
+
got += amt;
|
|
84
|
+
left -= cost;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return { got, spent: amountIn - left };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* A bonding buy of GROSS `amountInWei` (the fee rides on top). `tokenDecimals` is 18 on every EVM launch. `rounding` is the
|
|
92
|
+
* deployment's `ContractRules.saleCost` (default: the current contracts, `ceil`). `fillWei` is the least gross whose net
|
|
93
|
+
* walks to the end of the sale in that rounding.
|
|
94
|
+
*/
|
|
95
|
+
export function saleBuyQuote(s, amountInWei, tokenDecimals, rounding = 'ceil') {
|
|
96
|
+
const unit = 10n ** BigInt(tokenDecimals);
|
|
97
|
+
const all = walkBuy(s, UINT256_MAX, unit, rounding);
|
|
98
|
+
const fillWei = saleGrossFor(all.spent, s.teamFeeBps);
|
|
99
|
+
const q = walkBuy(s, saleNetOf(amountInWei, s.teamFeeBps), unit, rounding);
|
|
100
|
+
return { got: q.got, spent: q.spent, fee: teamFeeOf(q.spent, s.teamFeeBps), maxGot: all.got, fillWei, overfills: amountInWei > fillWei };
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* A sell-back of `tokens` (`FloorLaunch._sell`), less the sale's FLOOR Platform fee (`floor(payout × bps / 10_000)`).
|
|
104
|
+
* - `stateless` (the current contracts, default): `payout = tokens × p0 / 1e18` — the tokens at the sale's one price,
|
|
105
|
+
* rounded down — capped at the position's `contributed`.
|
|
106
|
+
* - `proRata` (older contracts): `payout = contributed × tokens / allocation`, rounded down.
|
|
107
|
+
* The position (`allocation` tokens bought for `contributed` quote) bounds both: `null` where the sale would revert
|
|
108
|
+
* (`tokens` zero or above the allocation).
|
|
109
|
+
*/
|
|
110
|
+
export function sellBackQuote(p0, contributed, allocation, tokens, teamFeeBps, rule = 'stateless') {
|
|
111
|
+
if (tokens <= 0n || allocation <= 0n || tokens > allocation)
|
|
112
|
+
return null;
|
|
113
|
+
let payout;
|
|
114
|
+
if (rule === 'proRata')
|
|
115
|
+
payout = (contributed * tokens) / allocation;
|
|
116
|
+
else {
|
|
117
|
+
const atPrice = (tokens * p0) / 10n ** 18n;
|
|
118
|
+
payout = atPrice > contributed ? contributed : atPrice;
|
|
119
|
+
}
|
|
120
|
+
const fee = teamFeeOf(payout, teamFeeBps);
|
|
121
|
+
return { payout, fee, paid: payout - fee };
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=sale.js.map
|
package/dist/sale.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sale.js","sourceRoot":"","sources":["../src/sale.ts"],"names":[],"mappings":"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"}
|
package/dist/send.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sending one action's calls with as few wallet prompts as the wallet allows.
|
|
3
|
+
*
|
|
4
|
+
* - EIP-5792: `wallet_getCapabilities` (for the account, at the chain id; the chain-agnostic `"0x0"` entry is read too,
|
|
5
|
+
* and the chain's own entry wins) says the wallet runs an ATOMIC batch there (`atomic.status` `supported` or `ready`; an
|
|
6
|
+
* older wallet's `atomicBatch.supported`) → ONE `wallet_sendCalls` with `atomicRequired`: one prompt, the approvals and
|
|
7
|
+
* the trade land or fail together. The batch id is handed to `onSubmitted` BEFORE any wait, then `waitForCallsStatus`
|
|
8
|
+
* waits for the receipts (`wait: false` returns at the id).
|
|
9
|
+
* - Otherwise (no 5792, no atomic batch on this chain, or the capabilities call fails): each call is sent in order with
|
|
10
|
+
* `eth_sendTransaction`, and its receipt awaited before the next — one prompt per call. A reverted call stops the sequence.
|
|
11
|
+
* - A `wallet_sendCalls` the wallet refuses as UNSUPPORTED (EIP-1193 4200, JSON-RPC -32601, EIP-5792 5700 / 5710 / 5760)
|
|
12
|
+
* has sent nothing, so the calls go the per-call way instead. Any other refusal (a user rejection, say) is thrown.
|
|
13
|
+
* ⛔ THE FALLBACK IS REQUIRED: some embedded wallets (Privy's, among them) do not implement `wallet_sendCalls`; a wallet
|
|
14
|
+
* that throws on `getCapabilities` (method not found) is sent the calls one by one.
|
|
15
|
+
* ⛔ A non-atomic 5792 batch is not used by default (`allowNonAtomic`): an approval could land without its trade.
|
|
16
|
+
* ⛔ AFTER A SUBMISSION, A FAILED WAIT IS NOT "NOTHING HAPPENED": a timeout or a failed status read throws
|
|
17
|
+
* `FloorEvmError('pending')` carrying the batch `id` / the `hashes` sent; keep waiting on those instead of re-sending.
|
|
18
|
+
* ⚠ Zero prompts happen only with an embedded wallet the integrator itself controls (it signs without asking); no
|
|
19
|
+
* browser wallet sends anything without the user's approval.
|
|
20
|
+
*/
|
|
21
|
+
import { type Account, type Address, type Chain, type Client, type Hex, type Transport } from 'viem';
|
|
22
|
+
import type { UnsignedTx } from '@floorlaunchpad/sdk';
|
|
23
|
+
/** How long `sendEvmCalls` waits for a batch's final status by default, ms. */
|
|
24
|
+
export declare const DEFAULT_BATCH_TIMEOUT_MS = 60000;
|
|
25
|
+
/** How long `sendEvmCalls` waits for each transaction's receipt on the per-call path by default, ms. */
|
|
26
|
+
export declare const DEFAULT_RECEIPT_TIMEOUT_MS = 180000;
|
|
27
|
+
/** Error codes with which a wallet refuses `wallet_sendCalls` as unsupported, before sending anything. */
|
|
28
|
+
export declare const SEND_CALLS_UNSUPPORTED_CODES: ReadonlySet<number>;
|
|
29
|
+
export interface SendEvmCallsOptions {
|
|
30
|
+
/** The sender. Defaults to the wallet client's own account. */
|
|
31
|
+
readonly account?: Account | Address;
|
|
32
|
+
/** Use a 5792 batch even where the wallet cannot make it atomic. Default false. */
|
|
33
|
+
readonly allowNonAtomic?: boolean;
|
|
34
|
+
/** Called once a 5792 batch is submitted, with its id, before any wait. Keep it: it is how to follow the batch. */
|
|
35
|
+
readonly onSubmitted?: (id: string) => void;
|
|
36
|
+
/** Called after each call on the per-call path, with its hash, before its receipt is awaited. */
|
|
37
|
+
readonly onSent?: (hash: Hex, index: number) => void;
|
|
38
|
+
/** Wait for the 5792 batch's receipts (`waitForCallsStatus`). Default true. */
|
|
39
|
+
readonly wait?: boolean;
|
|
40
|
+
/** How long to wait for the batch's final status, ms. Default `DEFAULT_BATCH_TIMEOUT_MS`. */
|
|
41
|
+
readonly batchTimeoutMs?: number;
|
|
42
|
+
/** How long to wait for each receipt on the per-call path, ms. Default `DEFAULT_RECEIPT_TIMEOUT_MS`. */
|
|
43
|
+
readonly receiptTimeoutMs?: number;
|
|
44
|
+
}
|
|
45
|
+
export type SendEvmCallsResult =
|
|
46
|
+
/** One prompt: the wallet's batch id (`wallet_getCallsStatus` / viem `waitForCallsStatus` follow it). */
|
|
47
|
+
{
|
|
48
|
+
readonly path: 'eip5792';
|
|
49
|
+
readonly id: string;
|
|
50
|
+
readonly atomic: boolean;
|
|
51
|
+
readonly hashes: readonly Hex[] | null;
|
|
52
|
+
}
|
|
53
|
+
/** One prompt per call: every transaction hash, in order, each mined successfully before the next was sent. */
|
|
54
|
+
| {
|
|
55
|
+
readonly path: 'transactions';
|
|
56
|
+
readonly hashes: readonly Hex[];
|
|
57
|
+
};
|
|
58
|
+
type Wallet = Client<Transport, Chain | undefined, Account | undefined>;
|
|
59
|
+
/** True when `e` is the wallet refusing `wallet_sendCalls` as unsupported (nothing was sent). */
|
|
60
|
+
export declare function isSendCallsUnsupported(e: unknown): boolean;
|
|
61
|
+
/** Sends `tx`'s calls in one EIP-5792 batch where the wallet supports an atomic one, else one transaction at a time. */
|
|
62
|
+
export declare function sendEvmCalls(wallet: Wallet, tx: UnsignedTx, opts?: SendEvmCallsOptions): Promise<SendEvmCallsResult>;
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAuC,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,MAAM,EAAE,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,MAAM,CAAC;AAG1I,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,+EAA+E;AAC/E,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAC/C,wGAAwG;AACxG,eAAO,MAAM,0BAA0B,SAAU,CAAC;AAElD,0GAA0G;AAC1G,eAAO,MAAM,4BAA4B,EAAE,WAAW,CAAC,MAAM,CAA6C,CAAC;AAE3G,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACrC,mFAAmF;IACnF,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,mHAAmH;IACnH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,iGAAiG;IACjG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,6FAA6F;IAC7F,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,wGAAwG;IACxG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,MAAM,kBAAkB;AAC5B,yGAAyG;AACvG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,EAAE,GAAG,IAAI,CAAA;CAAE;AACrH,+GAA+G;GAC7G;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,EAAE,CAAA;CAAE,CAAC;AAEvE,KAAK,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,KAAK,GAAG,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;AAmBxE,iGAAiG;AACjG,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAI1D;AAED,wHAAwH;AACxH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgD9H"}
|
package/dist/send.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sending one action's calls with as few wallet prompts as the wallet allows.
|
|
3
|
+
*
|
|
4
|
+
* - EIP-5792: `wallet_getCapabilities` (for the account, at the chain id; the chain-agnostic `"0x0"` entry is read too,
|
|
5
|
+
* and the chain's own entry wins) says the wallet runs an ATOMIC batch there (`atomic.status` `supported` or `ready`; an
|
|
6
|
+
* older wallet's `atomicBatch.supported`) → ONE `wallet_sendCalls` with `atomicRequired`: one prompt, the approvals and
|
|
7
|
+
* the trade land or fail together. The batch id is handed to `onSubmitted` BEFORE any wait, then `waitForCallsStatus`
|
|
8
|
+
* waits for the receipts (`wait: false` returns at the id).
|
|
9
|
+
* - Otherwise (no 5792, no atomic batch on this chain, or the capabilities call fails): each call is sent in order with
|
|
10
|
+
* `eth_sendTransaction`, and its receipt awaited before the next — one prompt per call. A reverted call stops the sequence.
|
|
11
|
+
* - A `wallet_sendCalls` the wallet refuses as UNSUPPORTED (EIP-1193 4200, JSON-RPC -32601, EIP-5792 5700 / 5710 / 5760)
|
|
12
|
+
* has sent nothing, so the calls go the per-call way instead. Any other refusal (a user rejection, say) is thrown.
|
|
13
|
+
* ⛔ THE FALLBACK IS REQUIRED: some embedded wallets (Privy's, among them) do not implement `wallet_sendCalls`; a wallet
|
|
14
|
+
* that throws on `getCapabilities` (method not found) is sent the calls one by one.
|
|
15
|
+
* ⛔ A non-atomic 5792 batch is not used by default (`allowNonAtomic`): an approval could land without its trade.
|
|
16
|
+
* ⛔ AFTER A SUBMISSION, A FAILED WAIT IS NOT "NOTHING HAPPENED": a timeout or a failed status read throws
|
|
17
|
+
* `FloorEvmError('pending')` carrying the batch `id` / the `hashes` sent; keep waiting on those instead of re-sending.
|
|
18
|
+
* ⚠ Zero prompts happen only with an embedded wallet the integrator itself controls (it signs without asking); no
|
|
19
|
+
* browser wallet sends anything without the user's approval.
|
|
20
|
+
*/
|
|
21
|
+
import { BaseError, defineChain, numberToHex } from 'viem';
|
|
22
|
+
import { parseAccount } from 'viem/accounts';
|
|
23
|
+
import { getChainId, sendCalls, sendTransaction, waitForCallsStatus, waitForTransactionReceipt } from 'viem/actions';
|
|
24
|
+
import { FloorEvmError } from './errors.js';
|
|
25
|
+
/** How long `sendEvmCalls` waits for a batch's final status by default, ms. */
|
|
26
|
+
export const DEFAULT_BATCH_TIMEOUT_MS = 60_000;
|
|
27
|
+
/** How long `sendEvmCalls` waits for each transaction's receipt on the per-call path by default, ms. */
|
|
28
|
+
export const DEFAULT_RECEIPT_TIMEOUT_MS = 180_000;
|
|
29
|
+
/** Error codes with which a wallet refuses `wallet_sendCalls` as unsupported, before sending anything. */
|
|
30
|
+
export const SEND_CALLS_UNSUPPORTED_CODES = new Set([4200, -32601, 5700, 5710, 5760]);
|
|
31
|
+
/** The wallet's capabilities for `chainId`: its chain-agnostic `"0x0"` entry with the chain's own entry over it. */
|
|
32
|
+
async function capabilitiesFor(wallet, account, chainId) {
|
|
33
|
+
const raw = (await wallet.request({ method: 'wallet_getCapabilities', params: [parseAccount(account).address, [numberToHex(chainId)]] }));
|
|
34
|
+
if (!raw || typeof raw !== 'object')
|
|
35
|
+
return undefined;
|
|
36
|
+
let any, own;
|
|
37
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
38
|
+
let n;
|
|
39
|
+
try {
|
|
40
|
+
n = Number(BigInt(k));
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (n === 0)
|
|
46
|
+
any = v;
|
|
47
|
+
else if (n === chainId)
|
|
48
|
+
own = v;
|
|
49
|
+
}
|
|
50
|
+
if (!any && !own)
|
|
51
|
+
return undefined;
|
|
52
|
+
return { ...(any ?? {}), ...(own ?? {}) };
|
|
53
|
+
}
|
|
54
|
+
/** True when `e` is the wallet refusing `wallet_sendCalls` as unsupported (nothing was sent). */
|
|
55
|
+
export function isSendCallsUnsupported(e) {
|
|
56
|
+
const hit = (x) => typeof x?.code === 'number' && SEND_CALLS_UNSUPPORTED_CODES.has(x.code);
|
|
57
|
+
if (e instanceof BaseError)
|
|
58
|
+
return e.walk(hit) !== null;
|
|
59
|
+
return hit(e);
|
|
60
|
+
}
|
|
61
|
+
/** Sends `tx`'s calls in one EIP-5792 batch where the wallet supports an atomic one, else one transaction at a time. */
|
|
62
|
+
export async function sendEvmCalls(wallet, tx, opts = {}) {
|
|
63
|
+
if (tx.family !== 'evm')
|
|
64
|
+
throw new FloorEvmError('bad_params', `sendEvmCalls sends EVM calls, not ${tx.family}`);
|
|
65
|
+
if (tx.calls.length === 0)
|
|
66
|
+
throw new FloorEvmError('bad_params', 'sendEvmCalls: no calls');
|
|
67
|
+
const account = opts.account ?? wallet.account;
|
|
68
|
+
if (!account)
|
|
69
|
+
throw new FloorEvmError('bad_params', 'sendEvmCalls: no account');
|
|
70
|
+
const on = await getChainId(wallet);
|
|
71
|
+
if (on !== tx.chainId)
|
|
72
|
+
throw new FloorEvmError('wrong_chain', `the wallet is on chain ${on}; these calls are for chain ${tx.chainId}`);
|
|
73
|
+
const chain = wallet.chain?.id === tx.chainId ? wallet.chain : defineChain({
|
|
74
|
+
id: tx.chainId, name: `chain ${tx.chainId}`, nativeCurrency: { name: 'native', symbol: 'native', decimals: 18 }, rpcUrls: { default: { http: [] } },
|
|
75
|
+
});
|
|
76
|
+
const calls = tx.calls.map((c) => ({ to: c.to, data: c.data, value: c.value, gas: c.gas }));
|
|
77
|
+
let atomic = null;
|
|
78
|
+
try {
|
|
79
|
+
const caps = await capabilitiesFor(wallet, account, tx.chainId);
|
|
80
|
+
const status = caps?.atomic?.status;
|
|
81
|
+
const can = status === 'supported' || status === 'ready' || caps?.atomicBatch?.supported === true;
|
|
82
|
+
atomic = can ? true : opts.allowNonAtomic && caps !== undefined ? false : null;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
atomic = null; // no EIP-5792 here
|
|
86
|
+
}
|
|
87
|
+
if (atomic !== null) {
|
|
88
|
+
let id = null;
|
|
89
|
+
try {
|
|
90
|
+
/* EIP-5792 calls carry no gas limit: the wallet estimates the batch. */
|
|
91
|
+
({ id } = await sendCalls(wallet, { account, chain, calls: calls.map(({ gas: _gas, ...c }) => c), forceAtomic: atomic }));
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
if (!isSendCallsUnsupported(e))
|
|
95
|
+
throw e;
|
|
96
|
+
id = null; // refused before sending anything: the per-call way below
|
|
97
|
+
}
|
|
98
|
+
if (id !== null)
|
|
99
|
+
return followBatch(wallet, id, atomic, opts);
|
|
100
|
+
}
|
|
101
|
+
const hashes = [];
|
|
102
|
+
const receiptTimeout = opts.receiptTimeoutMs ?? DEFAULT_RECEIPT_TIMEOUT_MS;
|
|
103
|
+
for (const [i, c] of calls.entries()) {
|
|
104
|
+
const hash = await sendTransaction(wallet, { account, chain, to: c.to, data: c.data, value: c.value, ...(c.gas !== undefined ? { gas: c.gas } : {}) });
|
|
105
|
+
hashes.push(hash);
|
|
106
|
+
opts.onSent?.(hash, i);
|
|
107
|
+
let status;
|
|
108
|
+
try {
|
|
109
|
+
({ status } = await waitForTransactionReceipt(wallet, { hash, timeout: receiptTimeout }));
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
throw new FloorEvmError('pending', `call ${i + 1} of ${calls.length} (${hash}) was sent but has no receipt yet; the rest were not sent. Keep waiting on it before sending again`, { cause: e, hashes: [...hashes] });
|
|
113
|
+
}
|
|
114
|
+
if (status !== 'success')
|
|
115
|
+
throw new FloorEvmError('reverted', `call ${i + 1} of ${calls.length} (${hash}) reverted; the rest were not sent`, { hashes: [...hashes] });
|
|
116
|
+
}
|
|
117
|
+
return { path: 'transactions', hashes };
|
|
118
|
+
}
|
|
119
|
+
async function followBatch(wallet, id, atomic, opts) {
|
|
120
|
+
opts.onSubmitted?.(id);
|
|
121
|
+
if (opts.wait === false)
|
|
122
|
+
return { path: 'eip5792', id, atomic, hashes: null };
|
|
123
|
+
let res;
|
|
124
|
+
try {
|
|
125
|
+
res = await waitForCallsStatus(wallet, { id, timeout: opts.batchTimeoutMs ?? DEFAULT_BATCH_TIMEOUT_MS });
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
throw new FloorEvmError('pending', `the batch ${id} was submitted; its outcome is not known yet. Keep waiting on it before sending again`, { cause: e, id });
|
|
129
|
+
}
|
|
130
|
+
const hashes = (res.receipts ?? []).map((r) => r.transactionHash);
|
|
131
|
+
if (res.status === 'success')
|
|
132
|
+
return { path: 'eip5792', id, atomic, hashes };
|
|
133
|
+
if (res.status === 'failure')
|
|
134
|
+
throw new FloorEvmError('batch_failed', `the batch ${id} ended failure`, { id, hashes });
|
|
135
|
+
throw new FloorEvmError('pending', `the batch ${id} is still ${res.status ?? 'unknown'}`, { id, hashes });
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=send.js.map
|
package/dist/send.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An off-chain simulator of a swap on a FLOOR pool: Uniswap v4's swap, ported from v4-core statement for statement, with the
|
|
3
|
+
* FLOOR hook's fees around it. It needs no network once it has a `SwapSnapshot` (`readSwapSnapshot`), and the same snapshot
|
|
4
|
+
* and amount always give the same answer, so an aggregator's router can call it as often as it likes.
|
|
5
|
+
*
|
|
6
|
+
* What the hook does to a trader's swap (`SingletonFloorEngine._beforeSwap` / `_afterSwap`):
|
|
7
|
+
* - Exact input only, both directions (`ExactOutNotSupported`).
|
|
8
|
+
* - A BUY (quote in): before the swap the hook takes its four fees off the quote paid in, at the skim rate of the PRE-swap
|
|
9
|
+
* price (the gap buy skim included where the set has it); the pool swaps what is left.
|
|
10
|
+
* - A SELL (tokens in): the pool swaps the tokens; after the swap the hook takes its four fees off the quote paid out, at the
|
|
11
|
+
* skim rate of the POST-swap price.
|
|
12
|
+
* - The LP fee is the pool's override, 0.25%, on every swap; v4's protocol fee, if any, composes with it as v4 does.
|
|
13
|
+
* The staircase, the cushion, the seed and the bid are ordinary positions in the pool; the walk below crosses them like any
|
|
14
|
+
* other liquidity. The in-swap bid re-place that follows a sell into the bid happens after the trader's amounts are settled,
|
|
15
|
+
* so it changes nothing here; it does change the pool for the NEXT swap, which is why a snapshot must be re-read after a sell
|
|
16
|
+
* that reached the band (`SwapResult.reachedBand`).
|
|
17
|
+
*/
|
|
18
|
+
import type { Hex, PublicClient } from 'viem';
|
|
19
|
+
import { type CushionEdge, type PoolRates } from './fees.js';
|
|
20
|
+
/** `SqrtPriceMath.getAmount0Delta(a, b, liquidity, roundUp)`. */
|
|
21
|
+
export declare function getAmount0Delta(a: bigint, b: bigint, liquidity: bigint, roundUp: boolean): bigint;
|
|
22
|
+
/** `SqrtPriceMath.getAmount1Delta(a, b, liquidity, roundUp)`. */
|
|
23
|
+
export declare function getAmount1Delta(a: bigint, b: bigint, liquidity: bigint, roundUp: boolean): bigint;
|
|
24
|
+
/** `SqrtPriceMath.getNextSqrtPriceFromInput`. */
|
|
25
|
+
export declare function getNextSqrtPriceFromInput(sqrtP: bigint, liquidity: bigint, amountIn: bigint, zeroForOne: boolean): bigint;
|
|
26
|
+
/** `SwapMath.computeSwapStep`, exact input only (an exact-output swap never reaches a FLOOR pool). */
|
|
27
|
+
export declare function computeSwapStepExactIn(sqrtCurrent: bigint, sqrtTarget: bigint, liquidity: bigint, amountRemaining: bigint, feePips: bigint): {
|
|
28
|
+
sqrtNext: bigint;
|
|
29
|
+
amountIn: bigint;
|
|
30
|
+
amountOut: bigint;
|
|
31
|
+
feeAmount: bigint;
|
|
32
|
+
};
|
|
33
|
+
/** `TickMath.getTickAtSqrtPrice`, exactly. */
|
|
34
|
+
export declare function getTickAtSqrtPrice(sqrtPriceX96: bigint): number;
|
|
35
|
+
/** A v4 pool as the swap walk reads it. Ticks are the PoolManager's own (raw, not the engine frame). */
|
|
36
|
+
export interface V4PoolState {
|
|
37
|
+
sqrtPriceX96: bigint;
|
|
38
|
+
tick: number;
|
|
39
|
+
liquidity: bigint;
|
|
40
|
+
tickSpacing: number;
|
|
41
|
+
/** v4's packed protocol fee (`Slot0.protocolFee`): zeroForOne in the low 12 bits, oneForZero in the next 12. */
|
|
42
|
+
protocolFee: number;
|
|
43
|
+
/** The tick bitmap, word position → word. A word left out is read as empty. */
|
|
44
|
+
bitmap: ReadonlyMap<number, bigint>;
|
|
45
|
+
/** `liquidityNet` of every initialized tick. */
|
|
46
|
+
liquidityNet: ReadonlyMap<number, bigint>;
|
|
47
|
+
}
|
|
48
|
+
export interface V4SwapResult {
|
|
49
|
+
/** The input the pool consumed, LP and protocol fees included. Less than asked only when the pool ran out of liquidity. */
|
|
50
|
+
amountIn: bigint;
|
|
51
|
+
amountOut: bigint;
|
|
52
|
+
/** The LP fee and v4's protocol fee charged, in the input token. */
|
|
53
|
+
lpFee: bigint;
|
|
54
|
+
protocolFee: bigint;
|
|
55
|
+
sqrtPriceX96: bigint;
|
|
56
|
+
tick: number;
|
|
57
|
+
liquidity: bigint;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* `Pool.swap`, exact input, with the price limit the V4Quoter and the UniversalRouter use when none is given (the edge of
|
|
61
|
+
* the price range). `lpFeePips` is the swap's LP fee (a FLOOR pool overrides it to 2,500 on every swap).
|
|
62
|
+
*/
|
|
63
|
+
export declare function v4SwapExactIn(pool: V4PoolState, zeroForOne: boolean, amountIn: bigint, lpFeePips: bigint, sqrtPriceLimitX96?: bigint): V4SwapResult;
|
|
64
|
+
/** Everything a FLOOR pool swap is computed from. Read it with `readSwapSnapshot`; refresh it after any swap on the pool. */
|
|
65
|
+
export interface SwapSnapshot {
|
|
66
|
+
pool: V4PoolState;
|
|
67
|
+
/** The quote is currency1 (an ERC-20 quote that sorts above the token); false for a native quote. */
|
|
68
|
+
quoteIsCurrency1: boolean;
|
|
69
|
+
/** `poolState.floorTick`, engine frame. */
|
|
70
|
+
floorTick: number;
|
|
71
|
+
rates: PoolRates;
|
|
72
|
+
cushion: CushionEdge;
|
|
73
|
+
/** The set has the gap buy skim (`ContractRules.gapSkim`). */
|
|
74
|
+
gapSkim: boolean;
|
|
75
|
+
}
|
|
76
|
+
export interface FloorSwapFees {
|
|
77
|
+
/** The v4 LP fee, in the swap's input token (the quote on a buy, the launch token on a sell). */
|
|
78
|
+
lp: bigint;
|
|
79
|
+
/** v4's protocol fee, in the input token; 0 unless the PoolManager's owner set one. */
|
|
80
|
+
protocol: bigint;
|
|
81
|
+
/** The hook's four takes, in the quote. */
|
|
82
|
+
floorSkim: bigint;
|
|
83
|
+
creator: bigint;
|
|
84
|
+
holder: bigint;
|
|
85
|
+
floorPlatform: bigint;
|
|
86
|
+
}
|
|
87
|
+
export interface FloorSwapResult {
|
|
88
|
+
side: 'buy' | 'sell';
|
|
89
|
+
amountIn: bigint;
|
|
90
|
+
amountOut: bigint;
|
|
91
|
+
/** The skim rate charged, bps. */
|
|
92
|
+
skimBps: number;
|
|
93
|
+
fees: FloorSwapFees;
|
|
94
|
+
/** The pool's price and tick after the swap (before any bid re-place). */
|
|
95
|
+
sqrtPriceX96After: bigint;
|
|
96
|
+
tickAfter: number;
|
|
97
|
+
/** A sell whose walk reached the bid band's dear edge: the hook re-places the bid after it, so re-read the snapshot. */
|
|
98
|
+
reachedBand: boolean;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Quote an exact-input swap on a FLOOR pool. `side` is the trader's: `buy` pays `amountIn` of the quote for launch tokens,
|
|
102
|
+
* `sell` pays `amountIn` launch tokens for the quote. Throws `no_quote` when the pool cannot fill the whole
|
|
103
|
+
* input (the V4Quoter refuses such a swap too).
|
|
104
|
+
*/
|
|
105
|
+
export declare function simulateSwap(s: SwapSnapshot, side: 'buy' | 'sell', amountIn: bigint): FloorSwapResult;
|
|
106
|
+
/** Uniswap v4's StateView: the four reads a snapshot needs. */
|
|
107
|
+
export declare const STATE_VIEW_ABI: readonly [{
|
|
108
|
+
readonly type: "function";
|
|
109
|
+
readonly name: "getSlot0";
|
|
110
|
+
readonly stateMutability: "view";
|
|
111
|
+
readonly inputs: readonly [{
|
|
112
|
+
readonly name: "poolId";
|
|
113
|
+
readonly type: "bytes32";
|
|
114
|
+
}];
|
|
115
|
+
readonly outputs: readonly [{
|
|
116
|
+
readonly name: "sqrtPriceX96";
|
|
117
|
+
readonly type: "uint160";
|
|
118
|
+
}, {
|
|
119
|
+
readonly name: "tick";
|
|
120
|
+
readonly type: "int24";
|
|
121
|
+
}, {
|
|
122
|
+
readonly name: "protocolFee";
|
|
123
|
+
readonly type: "uint24";
|
|
124
|
+
}, {
|
|
125
|
+
readonly name: "lpFee";
|
|
126
|
+
readonly type: "uint24";
|
|
127
|
+
}];
|
|
128
|
+
}, {
|
|
129
|
+
readonly type: "function";
|
|
130
|
+
readonly name: "getLiquidity";
|
|
131
|
+
readonly stateMutability: "view";
|
|
132
|
+
readonly inputs: readonly [{
|
|
133
|
+
readonly name: "poolId";
|
|
134
|
+
readonly type: "bytes32";
|
|
135
|
+
}];
|
|
136
|
+
readonly outputs: readonly [{
|
|
137
|
+
readonly name: "liquidity";
|
|
138
|
+
readonly type: "uint128";
|
|
139
|
+
}];
|
|
140
|
+
}, {
|
|
141
|
+
readonly type: "function";
|
|
142
|
+
readonly name: "getTickBitmap";
|
|
143
|
+
readonly stateMutability: "view";
|
|
144
|
+
readonly inputs: readonly [{
|
|
145
|
+
readonly name: "poolId";
|
|
146
|
+
readonly type: "bytes32";
|
|
147
|
+
}, {
|
|
148
|
+
readonly name: "tick";
|
|
149
|
+
readonly type: "int16";
|
|
150
|
+
}];
|
|
151
|
+
readonly outputs: readonly [{
|
|
152
|
+
readonly name: "tickBitmap";
|
|
153
|
+
readonly type: "uint256";
|
|
154
|
+
}];
|
|
155
|
+
}, {
|
|
156
|
+
readonly type: "function";
|
|
157
|
+
readonly name: "getTickLiquidity";
|
|
158
|
+
readonly stateMutability: "view";
|
|
159
|
+
readonly inputs: readonly [{
|
|
160
|
+
readonly name: "poolId";
|
|
161
|
+
readonly type: "bytes32";
|
|
162
|
+
}, {
|
|
163
|
+
readonly name: "tick";
|
|
164
|
+
readonly type: "int24";
|
|
165
|
+
}];
|
|
166
|
+
readonly outputs: readonly [{
|
|
167
|
+
readonly name: "liquidityGross";
|
|
168
|
+
readonly type: "uint128";
|
|
169
|
+
}, {
|
|
170
|
+
readonly name: "liquidityNet";
|
|
171
|
+
readonly type: "int128";
|
|
172
|
+
}];
|
|
173
|
+
}];
|
|
174
|
+
/**
|
|
175
|
+
* Read everything `simulateSwap` needs for one pool: the hook's `poolState` (rates, floor, orientation), the cushion, the
|
|
176
|
+
* PoolManager's slot0 and liquidity through StateView, the whole tick bitmap and every initialized tick's `liquidityNet`.
|
|
177
|
+
* About 120 bitmap reads plus one per initialized tick; batch them with a viem client that has `batch.multicall` set.
|
|
178
|
+
*/
|
|
179
|
+
export declare function readSwapSnapshot(client: PublicClient, chainId: number, poolId: Hex): Promise<SwapSnapshot>;
|
|
180
|
+
//# sourceMappingURL=simulate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulate.d.ts","sourceRoot":"","sources":["../src/simulate.ts"],"names":[],"mappings":"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"}
|