auctionflow-sdk 1.1.0 → 1.3.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/README.md CHANGED
@@ -56,7 +56,8 @@ Without it, constructing on a chain that has no built-in deployment throws.
56
56
  ## Create an auction
57
57
 
58
58
  The builder validates required fields and basic invariants (`startTime < endTime`,
59
- positive `basePrice` / `maxSupply` / `maxRaise`) before producing a config.
59
+ positive `basePrice` / `maxSupply` / `maxRaise`, a liquidity share between 20% and
60
+ 100%) before producing a config.
60
61
 
61
62
  ```typescript
62
63
  const config = sdk
@@ -68,6 +69,7 @@ const config = sdk
68
69
  parseUnits("0.000001", 6) // slope
69
70
  )
70
71
  .withMaxRaise(parseUnits("50000", 6))
72
+ .withLiquidity(5_000) // 50% of the raise seeds the Uniswap pool (the default)
71
73
  .withSchedule(
72
74
  BigInt(Math.floor(Date.now() / 1000) + 3600),
73
75
  BigInt(Math.floor(Date.now() / 1000) + 3600 * 72)
@@ -77,12 +79,36 @@ const config = sdk
77
79
  const hash = await sdk.createAuction(config);
78
80
  ```
79
81
 
82
+ `withLiquidity` sets the share of the raise, in basis points, that is paired
83
+ with newly minted tokens to open a Uniswap pool when the auction ends; the
84
+ creator receives the rest. The token supply must leave room for those tokens on
85
+ top of a sold-out sale, so the contract rejects a `maxSupply` that is too small.
86
+
87
+ Auction tokens can't be transferred until the auction migrates. That stops any
88
+ holder from creating or pricing the Uniswap pool ahead of the auction.
89
+
80
90
  ## Buy tokens
81
91
 
82
92
  ```typescript
83
93
  const hash = await sdk.buyTokens(0n, parseUnits("1000", 18));
84
94
  ```
85
95
 
96
+ Every purchase raises the price, so another buyer can move it between your
97
+ quote and your transaction. `buyTokens` sends a maximum total cost (cost plus
98
+ fee) and the contract reverts if the price moved past it. By default the SDK
99
+ quotes the purchase and allows 1% above that quote. To change the tolerance, or
100
+ set the bound yourself:
101
+
102
+ ```typescript
103
+ await sdk.buyTokens(0n, amount, { slippageBps: 50 }); // 0.5% tolerance
104
+ await sdk.buyTokens(0n, amount, { maxCost: 11_000_000n }); // exact bound, in USDC units
105
+ ```
106
+
107
+ A purchase that would take the auction past its `maxRaise` is filled with what
108
+ the remaining budget buys, and closes the auction. `getQuote` reports this up
109
+ front: `quote.amount` is what you'll actually receive and `quote.fillsAuction`
110
+ says whether your purchase completes the sale.
111
+
86
112
  ## Read state & quotes
87
113
 
88
114
  ```typescript
@@ -101,20 +127,38 @@ The bonding-curve helpers are also exported directly for UI/preview use:
101
127
  import { calculateBuyQuote, spotPrice } from "auctionflow-sdk";
102
128
  ```
103
129
 
104
- ## Withdraw proceeds
130
+ ## After the auction: migrate, withdraw, collect fees
105
131
 
106
- Once an auction reaches `COMPLETED` — either by hitting `maxRaise` or via
107
- `completeAuction` after `endTime` — its creator claims the raised payment
108
- tokens. Callable once, by the creator only.
132
+ Once an auction completes, by filling up or via `completeAuction` after
133
+ `endTime`, three things happen. Each can be called by anyone except the
134
+ withdrawal, which only the creator can make.
109
135
 
110
136
  ```typescript
137
+ // 1. Open the Uniswap v3 pool and unlock the token for trading.
138
+ await sdk.migrate(0n);
139
+ const { pool, positionId } = await sdk.getMigration(0n);
140
+
141
+ // 2. The creator claims their share of the raise.
111
142
  if (!(await sdk.hasWithdrawnProceeds(0n))) {
112
- const hash = await sdk.withdrawProceeds(0n);
143
+ await sdk.withdrawProceeds(0n);
113
144
  }
145
+
146
+ // 3. Later, collect the pool's trading fees.
147
+ await sdk.collectFees(0n);
114
148
  ```
115
149
 
116
- Protocol fees are routed to the fee recipient at buy time, so the amount paid
117
- out is exactly the auction's `totalRaised`.
150
+ **Migration** pairs the auction's liquidity share of the raise with newly
151
+ minted tokens and opens a 1% Uniswap v3 pool **at the auction's final price**,
152
+ so there is no price jump to arbitrage. If someone initialised the pool
153
+ beforehand at a different price, migration corrects it first. The position NFT
154
+ stays in the auction contract forever, so the liquidity can never be pulled.
155
+ Tokens Uniswap doesn't use are burned, and leftover funds go to the creator.
156
+
157
+ **Withdrawal** pays the creator everything not reserved for liquidity: with the
158
+ default 50% share, half the raise. It works before or after migration.
159
+
160
+ **Trading fees** from the pool go to the creator, minus the protocol's share
161
+ (`lpFeeShareBps`, at most 50%), fixed when the auction is created.
118
162
 
119
163
  ## How the bonding curve works
120
164
 
@@ -146,11 +190,15 @@ Early buyers pay less; later buyers pay more.
146
190
  | `new AuctionFlowSDK({ chainId, rpcUrl, walletClient?, auctionAddress? })` | Construct against a supported chain. `auctionAddress` overrides the built-in deployment; without it, a chain with no canonical deployment throws. |
147
191
  | `buildAuction()` | Returns an `AuctionBuilder` (fluent config builder). |
148
192
  | `createAuction(config)` | Send the `createAuction` transaction. Requires a wallet client. |
149
- | `buyTokens(auctionId, amount)` | Send the `buyTokens` transaction. Requires a wallet client. |
193
+ | `buyTokens(auctionId, amount, { maxCost?, slippageBps? })` | Send the `buyTokens` transaction with a maximum total cost; reverts if the price moved past it. Defaults to the quote plus 1%. Requires a wallet client. |
150
194
  | `getAuction(auctionId)` | Read the full auction struct. |
151
195
  | `getSpotPrice(auctionId)` | Read the current on-chain spot price. |
152
- | `getQuote(auctionId, amount)` | Off-chain cost + fee + post-trade spot price. |
153
- | `withdrawProceeds(auctionId)` | Pay a completed auction's `totalRaised` to its creator. Creator-only, once. Requires a wallet client. |
196
+ | `getQuote(auctionId, amount)` | Tokens actually filled, cost, fee, post-trade spot price, and whether the purchase completes the auction. |
197
+ | `applySlippage(total, slippageBps)` | The maximum cost `buyTokens` would send for a quoted total. |
198
+ | `migrate(auctionId)` | Open the Uniswap v3 pool at the final price, lock the liquidity, unlock the token. Anyone may call. |
199
+ | `getMigration(auctionId)` | The pool address and position NFT id, or `null` before migration. |
200
+ | `withdrawProceeds(auctionId)` | Pay the creator their share of the raise (what isn't reserved for liquidity). Creator-only, once. |
201
+ | `collectFees(auctionId)` | Collect the pool's trading fees: protocol share to the protocol, the rest to the creator. Anyone may call. |
154
202
  | `hasWithdrawnProceeds(auctionId)` | Whether the creator has already claimed the proceeds. |
155
203
 
156
204
  ## License
package/dist/index.d.mts CHANGED
@@ -16,6 +16,11 @@ interface AuctionConfig {
16
16
  maxRaise: bigint;
17
17
  startTime: bigint;
18
18
  endTime: bigint;
19
+ /**
20
+ * Share of the raise seeded into Uniswap at migration, in basis points
21
+ * (2000..10000). Defaults to 5000 (50%).
22
+ */
23
+ liquidityBps?: bigint;
19
24
  }
20
25
  interface AuctionData {
21
26
  id: bigint;
@@ -31,12 +36,25 @@ interface AuctionData {
31
36
  totalRaised: bigint;
32
37
  totalSold: bigint;
33
38
  protocolFeeBps: bigint;
39
+ liquidityBps: bigint;
40
+ /** Protocol's share of the Uniswap pool's trading fees, in basis points. */
41
+ lpFeeShareBps: bigint;
42
+ }
43
+ interface MigrationInfo {
44
+ /** The Uniswap v3 pool, or null if the auction unlocked without one. */
45
+ pool: Address | null;
46
+ /** The Uniswap position NFT, held by the auction contract forever. */
47
+ positionId: bigint | null;
34
48
  }
35
49
  interface BuyQuote {
50
+ /** Tokens the purchase would actually deliver: less than requested if it fills the auction. */
51
+ amount: bigint;
36
52
  cost: bigint;
37
53
  fee: bigint;
38
54
  totalCost: bigint;
39
55
  spotPriceAfter: bigint;
56
+ /** True if this purchase reaches the cap and closes the auction. */
57
+ fillsAuction: boolean;
40
58
  }
41
59
  interface TransactionResult {
42
60
  hash: Hash;
@@ -49,6 +67,12 @@ declare class AuctionBuilder {
49
67
  withPaymentToken(address: Address): this;
50
68
  withBondingCurve(basePrice: bigint, slope: bigint): this;
51
69
  withMaxRaise(maxRaise: bigint): this;
70
+ /**
71
+ * Share of the raise, in basis points, seeded into a Uniswap pool when the
72
+ * auction migrates (5000 = 50%). The rest goes to the creator. Defaults to
73
+ * 50%; must be between 20% and 100%.
74
+ */
75
+ withLiquidity(liquidityBps: number): this;
52
76
  withSchedule(startTime: bigint, endTime: bigint): this;
53
77
  build(): AuctionConfig;
54
78
  }
@@ -67,12 +91,38 @@ declare class AuctionFlowSDK {
67
91
  });
68
92
  buildAuction(): AuctionBuilder;
69
93
  createAuction(config: AuctionConfig): Promise<Hash>;
70
- buyTokens(auctionId: bigint, amount: bigint): Promise<Hash>;
71
94
  /**
72
- * Withdraw a completed auction's raised payment tokens to its creator.
73
- * Only the auction's creator can call this, and only once.
95
+ * Buy `amount` tokens (in token wei). The price rises with every purchase, so
96
+ * the contract takes a maximum total cost and reverts if the price moved past
97
+ * it before the transaction landed.
98
+ *
99
+ * Pass `maxCost` to set that bound exactly, or `slippageBps` to derive it
100
+ * from a fresh quote (default 100 = 1% above the quoted total).
101
+ */
102
+ buyTokens(auctionId: bigint, amount: bigint, options?: {
103
+ maxCost?: bigint;
104
+ slippageBps?: number;
105
+ }): Promise<Hash>;
106
+ /**
107
+ * Pay a completed auction's creator their share of the raise: everything
108
+ * not reserved for Uniswap liquidity. Creator only, once, before or after
109
+ * migration.
74
110
  */
75
111
  withdrawProceeds(auctionId: bigint): Promise<Hash>;
112
+ /**
113
+ * Move a completed auction's liquidity into a Uniswap v3 pool at the
114
+ * auction's final price, lock it, and unlock the token for trading. Anyone
115
+ * may call it.
116
+ */
117
+ migrate(auctionId: bigint): Promise<Hash>;
118
+ /**
119
+ * Collect the migrated pool's trading fees. The protocol takes its share and
120
+ * the creator receives the rest. Anyone may call it.
121
+ */
122
+ collectFees(auctionId: bigint): Promise<Hash>;
123
+ /** The Uniswap pool and position for a migrated auction. */
124
+ getMigration(auctionId: bigint): Promise<MigrationInfo>;
125
+ private write;
76
126
  hasWithdrawnProceeds(auctionId: bigint): Promise<boolean>;
77
127
  getAuction(auctionId: bigint): Promise<AuctionData>;
78
128
  getQuote(auctionId: bigint, amount: bigint): Promise<BuyQuote>;
@@ -83,9 +133,11 @@ declare class AuctionFlowSDK {
83
133
  declare const AUCTION_ADDRESSES: Record<SupportedChainId, Address>;
84
134
  declare const USDC_ADDRESSES: Record<SupportedChainId, Address>;
85
135
 
86
- /**
87
- * Off-chain bonding curve calculations (mirrors BondingCurve.sol)
88
- */
136
+ /** Smallest share of the raise an auction may commit to Uniswap liquidity (20%). Mirrors TokenAuction.MIN_LIQUIDITY_BPS. */
137
+ declare const MIN_LIQUIDITY_BPS = 2000;
138
+ /** Liquidity share the builder uses when none is given (50%). */
139
+ declare const DEFAULT_LIQUIDITY_BPS = 5000;
140
+
89
141
  declare function calculateBuyCost(currentSupply: bigint, amount: bigint, basePrice: bigint, slope: bigint): bigint;
90
142
  declare function spotPrice(currentSupply: bigint, basePrice: bigint, slope: bigint): bigint;
91
143
  declare function calculateBuyQuote(currentSupply: bigint, amount: bigint, basePrice: bigint, slope: bigint, feeBps: bigint): {
@@ -94,5 +146,28 @@ declare function calculateBuyQuote(currentSupply: bigint, amount: bigint, basePr
94
146
  total: bigint;
95
147
  spotPriceAfter: bigint;
96
148
  };
149
+ /** Default slippage tolerance for `buyTokens`, in basis points (100 = 1%). */
150
+ declare const DEFAULT_SLIPPAGE_BPS = 100;
151
+ /**
152
+ * Upper bound a buyer will accept for a quoted total, given a tolerance in
153
+ * basis points. Rounds up so a tolerance never comes out tighter than asked.
154
+ */
155
+ declare function applySlippage(total: bigint, slippageBps: number): bigint;
156
+ /**
157
+ * Largest amount (token wei) buyable from `currentSupply` for at most `budget`,
158
+ * capped at `upperBound`. Mirrors BondingCurve.maxBuyable (binary search).
159
+ */
160
+ declare function maxBuyable(currentSupply: bigint, budget: bigint, basePrice: bigint, slope: bigint, upperBound: bigint): bigint;
161
+ /**
162
+ * What a purchase of `requested` tokens actually fills, given how much the
163
+ * auction has left to raise. Mirrors TokenAuction._fill: a purchase that would
164
+ * overshoot the cap delivers what the remaining budget buys and closes the
165
+ * auction.
166
+ */
167
+ declare function fillPurchase(currentSupply: bigint, requested: bigint, basePrice: bigint, slope: bigint, totalRaised: bigint, maxRaise: bigint): {
168
+ amount: bigint;
169
+ cost: bigint;
170
+ fillsAuction: boolean;
171
+ };
97
172
 
98
- export { AUCTION_ADDRESSES, AuctionBuilder, type AuctionConfig, type AuctionData, AuctionFlowSDK, AuctionState, type BuyQuote, type SupportedChainId, type TransactionResult, USDC_ADDRESSES, calculateBuyCost, calculateBuyQuote, spotPrice };
173
+ export { AUCTION_ADDRESSES, AuctionBuilder, type AuctionConfig, type AuctionData, AuctionFlowSDK, AuctionState, type BuyQuote, DEFAULT_LIQUIDITY_BPS, DEFAULT_SLIPPAGE_BPS, MIN_LIQUIDITY_BPS, type MigrationInfo, type SupportedChainId, type TransactionResult, USDC_ADDRESSES, applySlippage, calculateBuyCost, calculateBuyQuote, fillPurchase, maxBuyable, spotPrice };
package/dist/index.d.ts CHANGED
@@ -16,6 +16,11 @@ interface AuctionConfig {
16
16
  maxRaise: bigint;
17
17
  startTime: bigint;
18
18
  endTime: bigint;
19
+ /**
20
+ * Share of the raise seeded into Uniswap at migration, in basis points
21
+ * (2000..10000). Defaults to 5000 (50%).
22
+ */
23
+ liquidityBps?: bigint;
19
24
  }
20
25
  interface AuctionData {
21
26
  id: bigint;
@@ -31,12 +36,25 @@ interface AuctionData {
31
36
  totalRaised: bigint;
32
37
  totalSold: bigint;
33
38
  protocolFeeBps: bigint;
39
+ liquidityBps: bigint;
40
+ /** Protocol's share of the Uniswap pool's trading fees, in basis points. */
41
+ lpFeeShareBps: bigint;
42
+ }
43
+ interface MigrationInfo {
44
+ /** The Uniswap v3 pool, or null if the auction unlocked without one. */
45
+ pool: Address | null;
46
+ /** The Uniswap position NFT, held by the auction contract forever. */
47
+ positionId: bigint | null;
34
48
  }
35
49
  interface BuyQuote {
50
+ /** Tokens the purchase would actually deliver: less than requested if it fills the auction. */
51
+ amount: bigint;
36
52
  cost: bigint;
37
53
  fee: bigint;
38
54
  totalCost: bigint;
39
55
  spotPriceAfter: bigint;
56
+ /** True if this purchase reaches the cap and closes the auction. */
57
+ fillsAuction: boolean;
40
58
  }
41
59
  interface TransactionResult {
42
60
  hash: Hash;
@@ -49,6 +67,12 @@ declare class AuctionBuilder {
49
67
  withPaymentToken(address: Address): this;
50
68
  withBondingCurve(basePrice: bigint, slope: bigint): this;
51
69
  withMaxRaise(maxRaise: bigint): this;
70
+ /**
71
+ * Share of the raise, in basis points, seeded into a Uniswap pool when the
72
+ * auction migrates (5000 = 50%). The rest goes to the creator. Defaults to
73
+ * 50%; must be between 20% and 100%.
74
+ */
75
+ withLiquidity(liquidityBps: number): this;
52
76
  withSchedule(startTime: bigint, endTime: bigint): this;
53
77
  build(): AuctionConfig;
54
78
  }
@@ -67,12 +91,38 @@ declare class AuctionFlowSDK {
67
91
  });
68
92
  buildAuction(): AuctionBuilder;
69
93
  createAuction(config: AuctionConfig): Promise<Hash>;
70
- buyTokens(auctionId: bigint, amount: bigint): Promise<Hash>;
71
94
  /**
72
- * Withdraw a completed auction's raised payment tokens to its creator.
73
- * Only the auction's creator can call this, and only once.
95
+ * Buy `amount` tokens (in token wei). The price rises with every purchase, so
96
+ * the contract takes a maximum total cost and reverts if the price moved past
97
+ * it before the transaction landed.
98
+ *
99
+ * Pass `maxCost` to set that bound exactly, or `slippageBps` to derive it
100
+ * from a fresh quote (default 100 = 1% above the quoted total).
101
+ */
102
+ buyTokens(auctionId: bigint, amount: bigint, options?: {
103
+ maxCost?: bigint;
104
+ slippageBps?: number;
105
+ }): Promise<Hash>;
106
+ /**
107
+ * Pay a completed auction's creator their share of the raise: everything
108
+ * not reserved for Uniswap liquidity. Creator only, once, before or after
109
+ * migration.
74
110
  */
75
111
  withdrawProceeds(auctionId: bigint): Promise<Hash>;
112
+ /**
113
+ * Move a completed auction's liquidity into a Uniswap v3 pool at the
114
+ * auction's final price, lock it, and unlock the token for trading. Anyone
115
+ * may call it.
116
+ */
117
+ migrate(auctionId: bigint): Promise<Hash>;
118
+ /**
119
+ * Collect the migrated pool's trading fees. The protocol takes its share and
120
+ * the creator receives the rest. Anyone may call it.
121
+ */
122
+ collectFees(auctionId: bigint): Promise<Hash>;
123
+ /** The Uniswap pool and position for a migrated auction. */
124
+ getMigration(auctionId: bigint): Promise<MigrationInfo>;
125
+ private write;
76
126
  hasWithdrawnProceeds(auctionId: bigint): Promise<boolean>;
77
127
  getAuction(auctionId: bigint): Promise<AuctionData>;
78
128
  getQuote(auctionId: bigint, amount: bigint): Promise<BuyQuote>;
@@ -83,9 +133,11 @@ declare class AuctionFlowSDK {
83
133
  declare const AUCTION_ADDRESSES: Record<SupportedChainId, Address>;
84
134
  declare const USDC_ADDRESSES: Record<SupportedChainId, Address>;
85
135
 
86
- /**
87
- * Off-chain bonding curve calculations (mirrors BondingCurve.sol)
88
- */
136
+ /** Smallest share of the raise an auction may commit to Uniswap liquidity (20%). Mirrors TokenAuction.MIN_LIQUIDITY_BPS. */
137
+ declare const MIN_LIQUIDITY_BPS = 2000;
138
+ /** Liquidity share the builder uses when none is given (50%). */
139
+ declare const DEFAULT_LIQUIDITY_BPS = 5000;
140
+
89
141
  declare function calculateBuyCost(currentSupply: bigint, amount: bigint, basePrice: bigint, slope: bigint): bigint;
90
142
  declare function spotPrice(currentSupply: bigint, basePrice: bigint, slope: bigint): bigint;
91
143
  declare function calculateBuyQuote(currentSupply: bigint, amount: bigint, basePrice: bigint, slope: bigint, feeBps: bigint): {
@@ -94,5 +146,28 @@ declare function calculateBuyQuote(currentSupply: bigint, amount: bigint, basePr
94
146
  total: bigint;
95
147
  spotPriceAfter: bigint;
96
148
  };
149
+ /** Default slippage tolerance for `buyTokens`, in basis points (100 = 1%). */
150
+ declare const DEFAULT_SLIPPAGE_BPS = 100;
151
+ /**
152
+ * Upper bound a buyer will accept for a quoted total, given a tolerance in
153
+ * basis points. Rounds up so a tolerance never comes out tighter than asked.
154
+ */
155
+ declare function applySlippage(total: bigint, slippageBps: number): bigint;
156
+ /**
157
+ * Largest amount (token wei) buyable from `currentSupply` for at most `budget`,
158
+ * capped at `upperBound`. Mirrors BondingCurve.maxBuyable (binary search).
159
+ */
160
+ declare function maxBuyable(currentSupply: bigint, budget: bigint, basePrice: bigint, slope: bigint, upperBound: bigint): bigint;
161
+ /**
162
+ * What a purchase of `requested` tokens actually fills, given how much the
163
+ * auction has left to raise. Mirrors TokenAuction._fill: a purchase that would
164
+ * overshoot the cap delivers what the remaining budget buys and closes the
165
+ * auction.
166
+ */
167
+ declare function fillPurchase(currentSupply: bigint, requested: bigint, basePrice: bigint, slope: bigint, totalRaised: bigint, maxRaise: bigint): {
168
+ amount: bigint;
169
+ cost: bigint;
170
+ fillsAuction: boolean;
171
+ };
97
172
 
98
- export { AUCTION_ADDRESSES, AuctionBuilder, type AuctionConfig, type AuctionData, AuctionFlowSDK, AuctionState, type BuyQuote, type SupportedChainId, type TransactionResult, USDC_ADDRESSES, calculateBuyCost, calculateBuyQuote, spotPrice };
173
+ export { AUCTION_ADDRESSES, AuctionBuilder, type AuctionConfig, type AuctionData, AuctionFlowSDK, AuctionState, type BuyQuote, DEFAULT_LIQUIDITY_BPS, DEFAULT_SLIPPAGE_BPS, MIN_LIQUIDITY_BPS, type MigrationInfo, type SupportedChainId, type TransactionResult, USDC_ADDRESSES, applySlippage, calculateBuyCost, calculateBuyQuote, fillPurchase, maxBuyable, spotPrice };