@whetstone-research/doppler-sdk 0.0.1-alpha.4 → 0.0.1-alpha.41
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 +21 -0
- package/README.md +227 -9
- package/dist/DopplerSDK.d.mts +36 -7
- package/dist/DopplerSDK.d.ts +36 -7
- package/dist/DopplerSDK.js +21 -11
- package/dist/DopplerSDK.mjs +20 -10
- package/dist/abis/bytecodes.d.mts +2 -1
- package/dist/abis/bytecodes.d.ts +2 -1
- package/dist/abis/bytecodes.js +8 -5
- package/dist/abis/bytecodes.mjs +1 -2
- package/dist/abis/index.d.mts +752 -57
- package/dist/abis/index.d.ts +752 -57
- package/dist/abis/index.js +34 -19
- package/dist/abis/index.mjs +2 -3
- package/dist/addresses.d.mts +13 -1
- package/dist/addresses.d.ts +13 -1
- package/dist/addresses.js +12 -5
- package/dist/addresses.mjs +1 -2
- package/dist/builders.d.mts +133 -12
- package/dist/builders.d.ts +133 -12
- package/dist/builders.js +8 -5
- package/dist/builders.mjs +2 -3
- package/dist/chunk-44PYMMCH.mjs +1520 -0
- package/dist/chunk-44PYMMCH.mjs.map +1 -0
- package/dist/{chunk-ER42VG7H.js → chunk-45OJGXN4.js} +4 -2
- package/dist/chunk-45OJGXN4.js.map +1 -0
- package/dist/chunk-4HM3ERBU.js +13 -0
- package/dist/chunk-4HM3ERBU.js.map +1 -0
- package/dist/{chunk-THNQAO5Y.mjs → chunk-65BSFCKK.mjs} +46 -6
- package/dist/chunk-65BSFCKK.mjs.map +1 -0
- package/dist/chunk-73SOFTOX.js +1522 -0
- package/dist/chunk-73SOFTOX.js.map +1 -0
- package/dist/{chunk-NDWBEGEN.mjs → chunk-7W72MFJO.mjs} +4 -3
- package/dist/chunk-7W72MFJO.mjs.map +1 -0
- package/dist/chunk-ADGPGPA3.mjs +40 -0
- package/dist/chunk-ADGPGPA3.mjs.map +1 -0
- package/dist/chunk-AINJQVZP.mjs +255 -0
- package/dist/chunk-AINJQVZP.mjs.map +1 -0
- package/dist/{chunk-6H6BP7GZ.mjs → chunk-BT3SCAHY.mjs} +2 -2
- package/dist/chunk-BT3SCAHY.mjs.map +1 -0
- package/dist/{chunk-IX32KFK3.js → chunk-C2GAWK2K.js} +2 -2
- package/dist/chunk-C2GAWK2K.js.map +1 -0
- package/dist/chunk-C5EPBZOZ.js +317 -0
- package/dist/chunk-C5EPBZOZ.js.map +1 -0
- package/dist/{chunk-OMN7RXR4.js → chunk-CIRZKWLL.js} +4 -2
- package/dist/chunk-CIRZKWLL.js.map +1 -0
- package/dist/{chunk-JHKPKTCV.js → chunk-E4OANJ7J.js} +383 -30
- package/dist/chunk-E4OANJ7J.js.map +1 -0
- package/dist/chunk-ECD4FV3A.mjs +11 -0
- package/dist/chunk-ECD4FV3A.mjs.map +1 -0
- package/dist/{chunk-376RZEND.js → chunk-EFTJVQHS.js} +100 -68
- package/dist/chunk-EFTJVQHS.js.map +1 -0
- package/dist/{chunk-T644D54P.mjs → chunk-F7U377SD.mjs} +4 -3
- package/dist/chunk-F7U377SD.mjs.map +1 -0
- package/dist/{chunk-DEFXRGPD.mjs → chunk-H6JN7KCJ.mjs} +25 -10
- package/dist/chunk-H6JN7KCJ.mjs.map +1 -0
- package/dist/chunk-HGLO5LDS.mjs +3 -0
- package/dist/{chunk-CYDWEPFL.mjs.map → chunk-HGLO5LDS.mjs.map} +1 -1
- package/dist/{chunk-677KDMY7.mjs → chunk-I5K7TMG3.mjs} +29 -19
- package/dist/chunk-I5K7TMG3.mjs.map +1 -0
- package/dist/chunk-ITN5EO2T.js +45 -0
- package/dist/chunk-ITN5EO2T.js.map +1 -0
- package/dist/{chunk-G4X44AWK.js → chunk-KMGO45KZ.js} +40 -30
- package/dist/chunk-KMGO45KZ.js.map +1 -0
- package/dist/{chunk-TOMVBPNZ.js → chunk-LS4TK6SX.js} +9 -4
- package/dist/chunk-LS4TK6SX.js.map +1 -0
- package/dist/chunk-O2QILOKJ.mjs +315 -0
- package/dist/chunk-O2QILOKJ.mjs.map +1 -0
- package/dist/chunk-OVSI43QO.js +257 -0
- package/dist/chunk-OVSI43QO.js.map +1 -0
- package/dist/{chunk-OPKQMN46.mjs → chunk-PAPXGPJB.mjs} +9 -4
- package/dist/chunk-PAPXGPJB.mjs.map +1 -0
- package/dist/chunk-RAFSIZDB.mjs +471 -0
- package/dist/chunk-RAFSIZDB.mjs.map +1 -0
- package/dist/chunk-V2DF2GUE.js +4 -0
- package/dist/{chunk-DRBRT57F.js.map → chunk-V2DF2GUE.js.map} +1 -1
- package/dist/{chunk-JSJSYBHG.mjs → chunk-WTKJ2OCS.mjs} +79 -47
- package/dist/chunk-WTKJ2OCS.mjs.map +1 -0
- package/dist/chunk-XYBEODKJ.js +122 -0
- package/dist/chunk-XYBEODKJ.js.map +1 -0
- package/dist/{chunk-XJGF77WN.mjs → chunk-YCLVZS7E.mjs} +381 -31
- package/dist/chunk-YCLVZS7E.mjs.map +1 -0
- package/dist/{chunk-UYYQHQRJ.js → chunk-YSDTNI6S.js} +26 -9
- package/dist/chunk-YSDTNI6S.js.map +1 -0
- package/dist/chunk-Z7ZKBAUR.js +475 -0
- package/dist/chunk-Z7ZKBAUR.js.map +1 -0
- package/dist/constants.d.mts +2 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.js +41 -38
- package/dist/constants.mjs +1 -2
- package/dist/entities/DopplerFactory.d.mts +116 -8
- package/dist/entities/DopplerFactory.d.ts +116 -8
- package/dist/entities/DopplerFactory.js +11 -7
- package/dist/entities/DopplerFactory.mjs +10 -6
- package/dist/entities/auction/DynamicAuction.d.mts +13 -4
- package/dist/entities/auction/DynamicAuction.d.ts +13 -4
- package/dist/entities/auction/DynamicAuction.js +5 -6
- package/dist/entities/auction/DynamicAuction.mjs +4 -5
- package/dist/entities/auction/StaticAuction.d.mts +6 -3
- package/dist/entities/auction/StaticAuction.d.ts +6 -3
- package/dist/entities/auction/StaticAuction.js +5 -6
- package/dist/entities/auction/StaticAuction.mjs +4 -5
- package/dist/entities/auction/index.d.mts +2 -0
- package/dist/entities/auction/index.d.ts +2 -0
- package/dist/entities/auction/index.js +7 -8
- package/dist/entities/auction/index.mjs +5 -6
- package/dist/entities/quoter/Quoter.d.mts +44 -2
- package/dist/entities/quoter/Quoter.d.ts +44 -2
- package/dist/entities/quoter/Quoter.js +5 -6
- package/dist/entities/quoter/Quoter.mjs +4 -5
- package/dist/entities/quoter/index.d.mts +3 -0
- package/dist/entities/quoter/index.d.ts +3 -0
- package/dist/entities/quoter/index.js +5 -6
- package/dist/entities/quoter/index.mjs +4 -5
- package/dist/entities/token/derc20/Derc20.d.mts +33 -7
- package/dist/entities/token/derc20/Derc20.d.ts +33 -7
- package/dist/entities/token/derc20/Derc20.js +4 -5
- package/dist/entities/token/derc20/Derc20.mjs +3 -4
- package/dist/entities/token/derc20/index.d.mts +3 -0
- package/dist/entities/token/derc20/index.d.ts +3 -0
- package/dist/entities/token/derc20/index.js +4 -5
- package/dist/entities/token/derc20/index.mjs +3 -4
- package/dist/entities/token/eth/Eth.d.mts +7 -3
- package/dist/entities/token/eth/Eth.d.ts +7 -3
- package/dist/entities/token/eth/Eth.js +2 -3
- package/dist/entities/token/eth/Eth.mjs +1 -2
- package/dist/entities/token/eth/index.d.mts +3 -0
- package/dist/entities/token/eth/index.d.ts +3 -0
- package/dist/entities/token/eth/index.js +2 -3
- package/dist/entities/token/eth/index.mjs +1 -2
- package/dist/entities/token/index.d.mts +3 -0
- package/dist/entities/token/index.d.ts +3 -0
- package/dist/entities/token/index.js +6 -7
- package/dist/entities/token/index.mjs +4 -5
- package/dist/index.d.mts +10 -7
- package/dist/index.d.ts +10 -7
- package/dist/index.js +143 -94
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +19 -18
- package/dist/index.mjs.map +1 -1
- package/dist/types.d.mts +108 -13
- package/dist/types.d.ts +108 -13
- package/dist/types.js +3 -3
- package/dist/types.mjs +2 -2
- package/dist/utils/airlock.d.mts +11 -0
- package/dist/utils/airlock.d.ts +11 -0
- package/dist/utils/airlock.js +25 -0
- package/dist/utils/airlock.js.map +1 -0
- package/dist/utils/airlock.mjs +4 -0
- package/dist/utils/airlock.mjs.map +1 -0
- package/dist/utils/balanceDelta.d.mts +10 -0
- package/dist/utils/balanceDelta.d.ts +10 -0
- package/dist/utils/balanceDelta.js +12 -0
- package/dist/utils/balanceDelta.js.map +1 -0
- package/dist/utils/balanceDelta.mjs +3 -0
- package/dist/utils/balanceDelta.mjs.map +1 -0
- package/dist/utils/index.d.mts +6 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +24 -2
- package/dist/utils/index.mjs +4 -2
- package/dist/utils/priceHelpers.js +0 -1
- package/dist/utils/priceHelpers.mjs +0 -1
- package/dist/utils/tickMath.js +0 -1
- package/dist/utils/tickMath.mjs +0 -1
- package/package.json +8 -10
- package/dist/__tests__/mocks/addresses.d.mts +0 -45
- package/dist/__tests__/mocks/addresses.d.ts +0 -45
- package/dist/__tests__/mocks/addresses.js +0 -53
- package/dist/__tests__/mocks/addresses.js.map +0 -1
- package/dist/__tests__/mocks/addresses.mjs +0 -44
- package/dist/__tests__/mocks/addresses.mjs.map +0 -1
- package/dist/__tests__/mocks/clients.d.mts +0 -22
- package/dist/__tests__/mocks/clients.d.ts +0 -22
- package/dist/__tests__/mocks/clients.js +0 -17088
- package/dist/__tests__/mocks/clients.js.map +0 -1
- package/dist/__tests__/mocks/clients.mjs +0 -17084
- package/dist/__tests__/mocks/clients.mjs.map +0 -1
- package/dist/chunk-376RZEND.js.map +0 -1
- package/dist/chunk-65NYPZFH.mjs +0 -160
- package/dist/chunk-65NYPZFH.mjs.map +0 -1
- package/dist/chunk-677KDMY7.mjs.map +0 -1
- package/dist/chunk-6H6BP7GZ.mjs.map +0 -1
- package/dist/chunk-CEBZTG4L.js +0 -82
- package/dist/chunk-CEBZTG4L.js.map +0 -1
- package/dist/chunk-CYDWEPFL.mjs +0 -3
- package/dist/chunk-DEFXRGPD.mjs.map +0 -1
- package/dist/chunk-DRBRT57F.js +0 -4
- package/dist/chunk-EMXBYWZR.js +0 -162
- package/dist/chunk-EMXBYWZR.js.map +0 -1
- package/dist/chunk-ER42VG7H.js.map +0 -1
- package/dist/chunk-G4X44AWK.js.map +0 -1
- package/dist/chunk-IX32KFK3.js.map +0 -1
- package/dist/chunk-IZH2Z3KC.mjs +0 -757
- package/dist/chunk-IZH2Z3KC.mjs.map +0 -1
- package/dist/chunk-JHKPKTCV.js.map +0 -1
- package/dist/chunk-JSJSYBHG.mjs.map +0 -1
- package/dist/chunk-K7ZUQXWH.js +0 -759
- package/dist/chunk-K7ZUQXWH.js.map +0 -1
- package/dist/chunk-KEXKKQVW.js +0 -42
- package/dist/chunk-KEXKKQVW.js.map +0 -1
- package/dist/chunk-L4TKYN6R.mjs +0 -207
- package/dist/chunk-L4TKYN6R.mjs.map +0 -1
- package/dist/chunk-LOROXNH3.mjs +0 -37
- package/dist/chunk-LOROXNH3.mjs.map +0 -1
- package/dist/chunk-NDWBEGEN.mjs.map +0 -1
- package/dist/chunk-NURZN25J.js +0 -266
- package/dist/chunk-NURZN25J.js.map +0 -1
- package/dist/chunk-OMN7RXR4.js.map +0 -1
- package/dist/chunk-OPKQMN46.mjs.map +0 -1
- package/dist/chunk-T644D54P.mjs.map +0 -1
- package/dist/chunk-THNQAO5Y.mjs.map +0 -1
- package/dist/chunk-TMXOB6MR.mjs +0 -263
- package/dist/chunk-TMXOB6MR.mjs.map +0 -1
- package/dist/chunk-TOMVBPNZ.js.map +0 -1
- package/dist/chunk-UYYQHQRJ.js.map +0 -1
- package/dist/chunk-XJGF77WN.mjs.map +0 -1
- package/dist/chunk-YPNUUFAD.js +0 -209
- package/dist/chunk-YPNUUFAD.js.map +0 -1
- package/dist/magic-string.es-NMLAOY5A.js +0 -1298
- package/dist/magic-string.es-NMLAOY5A.js.map +0 -1
- package/dist/magic-string.es-QCVTE6QG.mjs +0 -1292
- package/dist/magic-string.es-QCVTE6QG.mjs.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Whetstone Research
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ The Doppler SDK consolidates functionality from the previous `doppler-v3-sdk` an
|
|
|
10
10
|
|
|
11
11
|
- **Static Auctions**: Fixed price range liquidity bootstrapping using Uniswap V3
|
|
12
12
|
- **Dynamic Auctions**: Gradual Dutch auctions using Uniswap V4 hooks
|
|
13
|
+
- **Multicurve Initializer**: Seed Uniswap V4 pools across multiple curves
|
|
13
14
|
- **Flexible Migration**: Support for migrating to Uniswap V2, V3, or V4
|
|
14
15
|
- **Token Management**: Built-in support for DERC20 tokens with vesting
|
|
15
16
|
- **Type Safety**: Full TypeScript support with discriminated unions
|
|
@@ -108,6 +109,16 @@ const params = new DynamicAuctionBuilder()
|
|
|
108
109
|
],
|
|
109
110
|
},
|
|
110
111
|
})
|
|
112
|
+
// Optional: override module addresses instead of chain defaults
|
|
113
|
+
.withAirlock('0xAirlock...')
|
|
114
|
+
.withPoolManager('0xPoolMgr...')
|
|
115
|
+
.withDopplerDeployer('0xDeployer...')
|
|
116
|
+
.withTokenFactory('0xFactory...')
|
|
117
|
+
.withV4Initializer('0xInitializer...')
|
|
118
|
+
.withGovernanceFactory('0xGovFactory...') // used for both standard and no‑op governance
|
|
119
|
+
// .withV2Migrator('0xV2Migrator...')
|
|
120
|
+
// .withV3Migrator('0xV3Migrator...')
|
|
121
|
+
// .withV4Migrator('0xV4Migrator...')
|
|
111
122
|
.withUserAddress('0x...')
|
|
112
123
|
.build()
|
|
113
124
|
|
|
@@ -116,6 +127,54 @@ console.log('Hook address:', result.hookAddress)
|
|
|
116
127
|
console.log('Token address:', result.tokenAddress)
|
|
117
128
|
```
|
|
118
129
|
|
|
130
|
+
### Multicurve Auction (V4 Multicurve Initializer)
|
|
131
|
+
|
|
132
|
+
Multicurve auctions use a Uniswap V4-style initializer that seeds liquidity across multiple curves in a single pool. This enables richer distributions and can be combined with any supported migration path (V2, V3, or V4).
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { MulticurveBuilder } from '@whetstone-research/doppler-sdk'
|
|
136
|
+
import { parseEther } from 'viem'
|
|
137
|
+
|
|
138
|
+
const params = new MulticurveBuilder(base.id)
|
|
139
|
+
.tokenConfig({ name: 'My Token', symbol: 'MTK', tokenURI: 'https://example.com/metadata.json' })
|
|
140
|
+
.saleConfig({ initialSupply: parseEther('1000000'), numTokensToSell: parseEther('900000'), numeraire: '0x...' })
|
|
141
|
+
.withMulticurveAuction({
|
|
142
|
+
fee: 0,
|
|
143
|
+
tickSpacing: 8,
|
|
144
|
+
curves: [
|
|
145
|
+
{ tickLower: 0, tickUpper: 240000, numPositions: 10, shares: parseEther('0.5') },
|
|
146
|
+
{ tickLower: 16000, tickUpper: 240000, numPositions: 10, shares: parseEther('0.5') },
|
|
147
|
+
],
|
|
148
|
+
// Optional: lock fee revenue to beneficiaries (shares in WAD)
|
|
149
|
+
lockableBeneficiaries: [
|
|
150
|
+
{ beneficiary: '0x...', shares: parseEther('0.05') },
|
|
151
|
+
],
|
|
152
|
+
})
|
|
153
|
+
.withGovernance({ type: 'default' })
|
|
154
|
+
// Choose a migration path (V2, V3, or V4). Example uses V2
|
|
155
|
+
.withMigration({ type: 'uniswapV2' })
|
|
156
|
+
// Optional address overrides if not provided by chain config
|
|
157
|
+
// .withV4MulticurveInitializer('0xInitializer...')
|
|
158
|
+
.withUserAddress('0x...')
|
|
159
|
+
.build()
|
|
160
|
+
|
|
161
|
+
const result = await sdk.factory.createMulticurve(params)
|
|
162
|
+
console.log('Pool address:', result.poolAddress)
|
|
163
|
+
console.log('Token address:', result.tokenAddress)
|
|
164
|
+
|
|
165
|
+
// Or simulate to preview addresses and gas without sending a transaction
|
|
166
|
+
const { asset, pool, gasEstimate } = await sdk.factory.simulateCreateMulticurve(params)
|
|
167
|
+
console.log('Estimated gas:', gasEstimate?.toString() ?? 'not available')
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### Transaction gas override
|
|
171
|
+
- You can pass a gas limit to factory create calls via the `gas` field on `CreateStaticAuctionParams` / `CreateDynamicAuctionParams` / `CreateMulticurveParams`.
|
|
172
|
+
- If omitted, the SDK uses the simulation's gas estimate when available, falling back to 13,500,000 gas for the `create()` transaction.
|
|
173
|
+
- `simulateCreate*` helpers now return `gasEstimate` so you can tune overrides before sending.
|
|
174
|
+
- Builders expose `.withGasLimit(gas: bigint)` so you can set overrides fluently.
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
119
178
|
### Builder Pattern (Recommended)
|
|
120
179
|
|
|
121
180
|
Prefer using the builders to construct `CreateStaticAuctionParams` and `CreateDynamicAuctionParams` fluently and safely. Builders apply sensible defaults and can compute ticks and gamma for you.
|
|
@@ -229,9 +288,8 @@ const currentEpoch = await auction.getCurrentEpoch();
|
|
|
229
288
|
The SDK includes full support for DERC20 tokens with vesting functionality:
|
|
230
289
|
|
|
231
290
|
```typescript
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const token = new Derc20(publicClient, walletClient, tokenAddress);
|
|
291
|
+
// Get a DERC20 instance from the SDK (uses its clients)
|
|
292
|
+
const token = sdk.getDerc20(tokenAddress);
|
|
235
293
|
|
|
236
294
|
// Read token information
|
|
237
295
|
const name = await token.getName();
|
|
@@ -243,10 +301,100 @@ const vestingData = await token.getVestingData(address);
|
|
|
243
301
|
console.log('Total vested:', vestingData.totalAmount);
|
|
244
302
|
console.log('Released:', vestingData.releasedAmount);
|
|
245
303
|
|
|
246
|
-
// Release vested tokens
|
|
247
|
-
await token.release(
|
|
304
|
+
// Release currently available vested tokens
|
|
305
|
+
await token.release();
|
|
248
306
|
```
|
|
249
307
|
|
|
308
|
+
Alternatively, you can instantiate directly if needed:
|
|
309
|
+
```typescript
|
|
310
|
+
import { Derc20 } from '@whetstone-research/doppler-sdk'
|
|
311
|
+
const tokenDirect = new Derc20(publicClient, walletClient, tokenAddress)
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Governance Delegation (ERC20Votes)
|
|
315
|
+
|
|
316
|
+
DERC20 extends OpenZeppelin's ERC20Votes. Voting power is tracked via checkpoints and only updates once an address delegates voting power (typically to itself). The SDK exposes simple read/write helpers for delegation.
|
|
317
|
+
|
|
318
|
+
Basics:
|
|
319
|
+
```ts
|
|
320
|
+
import { Derc20 } from '@whetstone-research/doppler-sdk'
|
|
321
|
+
|
|
322
|
+
const token = sdk.getDerc20(tokenAddress)
|
|
323
|
+
|
|
324
|
+
// Read: who an account delegates to, and current voting power
|
|
325
|
+
const currentDelegate = await token.getDelegates(userAddress)
|
|
326
|
+
const votes = await token.getVotes(userAddress)
|
|
327
|
+
|
|
328
|
+
// Self‑delegate to activate vote tracking
|
|
329
|
+
await token.delegate(userAddress)
|
|
330
|
+
|
|
331
|
+
// Or delegate to another address
|
|
332
|
+
await token.delegate('0xDelegatee...')
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Historical votes:
|
|
336
|
+
```ts
|
|
337
|
+
// OZ v5 uses timepoints (block numbers for block‑based clocks)
|
|
338
|
+
const blockNumber = await publicClient.getBlockNumber()
|
|
339
|
+
const pastVotes = await token.getPastVotes(userAddress, blockNumber - 1n)
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Signature‑based delegation (delegateBySig):
|
|
343
|
+
```ts
|
|
344
|
+
// Signs an EIP‑712 message and submits a transaction calling delegateBySig
|
|
345
|
+
// Note: This still submits a transaction from the connected wallet.
|
|
346
|
+
const expiry = BigInt(Math.floor(Date.now() / 1000) + 3600) // 1h
|
|
347
|
+
await token.delegateBySig('0xDelegatee...', expiry)
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Advanced: gasless delegation via relayer
|
|
351
|
+
- The token supports `delegateBySig(delegatee, nonce, expiry, v, r, s)`. A relayer can submit this on behalf of the user if it holds ETH for gas.
|
|
352
|
+
- To do this, have the user sign typed data, then send the signature to your backend that calls the contract.
|
|
353
|
+
|
|
354
|
+
Client (sign only):
|
|
355
|
+
```ts
|
|
356
|
+
const [nonce, name] = await Promise.all([
|
|
357
|
+
publicClient.readContract({ address: tokenAddress, abi: derc20Abi, functionName: 'nonces', args: [userAddress] }),
|
|
358
|
+
token.getName(),
|
|
359
|
+
])
|
|
360
|
+
const chainId = await publicClient.getChainId()
|
|
361
|
+
const domain = { name, version: '1', chainId, verifyingContract: tokenAddress } as const
|
|
362
|
+
const types = { Delegation: [
|
|
363
|
+
{ name: 'delegatee', type: 'address' },
|
|
364
|
+
{ name: 'nonce', type: 'uint256' },
|
|
365
|
+
{ name: 'expiry', type: 'uint256' },
|
|
366
|
+
] } as const
|
|
367
|
+
const message = { delegatee: '0xDelegatee...', nonce, expiry } as const
|
|
368
|
+
|
|
369
|
+
const signature = await walletClient.signTypedData({
|
|
370
|
+
domain, types, primaryType: 'Delegation', message, account: userAddress,
|
|
371
|
+
})
|
|
372
|
+
// POST { signature, delegatee, nonce, expiry } to your relayer
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Relayer (submit tx):
|
|
376
|
+
```ts
|
|
377
|
+
function splitSig(sig: `0x${string}`) {
|
|
378
|
+
const r = `0x${sig.slice(2, 66)}` as `0x${string}`
|
|
379
|
+
const s = `0x${sig.slice(66, 130)}` as `0x${string}`
|
|
380
|
+
let v = parseInt(sig.slice(130, 132), 16); if (v < 27) v += 27
|
|
381
|
+
return { v, r, s }
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const { v, r, s } = splitSig(signature)
|
|
385
|
+
await relayerWallet.writeContract({
|
|
386
|
+
address: tokenAddress,
|
|
387
|
+
abi: derc20Abi,
|
|
388
|
+
functionName: 'delegateBySig',
|
|
389
|
+
args: ['0xDelegatee...', nonce, expiry, v, r, s],
|
|
390
|
+
})
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Notes
|
|
394
|
+
- Users must delegate (even to themselves) before votes appear in `getVotes`.
|
|
395
|
+
- `getPastVotes`/`getPastTotalSupply` expect a timepoint; for block‑based clocks, pass a block number that has already been mined.
|
|
396
|
+
- Events you may track: `DelegateChanged` and `DelegateVotesChanged` for live updates.
|
|
397
|
+
|
|
250
398
|
### Native ETH
|
|
251
399
|
|
|
252
400
|
The SDK also provides an ETH wrapper with ERC20-like interface:
|
|
@@ -278,6 +426,18 @@ console.log('Expected output:', quote.amountOut);
|
|
|
278
426
|
console.log('Price after swap:', quote.sqrtPriceX96After);
|
|
279
427
|
```
|
|
280
428
|
|
|
429
|
+
## Atomic Create + Pre‑Buy (Bundle)
|
|
430
|
+
|
|
431
|
+
For static auctions, you can create the pool and execute a pre‑buy in a single transaction via the Bundler.
|
|
432
|
+
|
|
433
|
+
High‑level flow:
|
|
434
|
+
- Simulate create to get `CreateParams` and the predicted token address
|
|
435
|
+
- Decide `amountOut` to buy, simulate `amountIn` with `simulateBundleExactOutput(...)`
|
|
436
|
+
- Build Universal Router commands (e.g., via `doppler-router`)
|
|
437
|
+
- Call `factory.bundle(createParams, commands, inputs, { value })`
|
|
438
|
+
|
|
439
|
+
See docs/quotes-and-swaps.md for a full example.
|
|
440
|
+
|
|
281
441
|
## Migration Configuration
|
|
282
442
|
|
|
283
443
|
The SDK supports flexible migration paths after auction completion:
|
|
@@ -313,12 +473,67 @@ migration: {
|
|
|
313
473
|
}
|
|
314
474
|
```
|
|
315
475
|
|
|
476
|
+
To make configuring the first beneficiary simpler, the SDK now exposes helpers for resolving the
|
|
477
|
+
airlock owner and creating the default 5% entry:
|
|
478
|
+
|
|
479
|
+
```ts
|
|
480
|
+
import { DopplerSDK, createAirlockBeneficiary, getAirlockOwner } from '@whetstone-research/doppler-sdk'
|
|
481
|
+
|
|
482
|
+
const sdk = new DopplerSDK({ publicClient, chainId })
|
|
483
|
+
|
|
484
|
+
// Get the owner and construct the beneficiary entry (5% by default)
|
|
485
|
+
const airlockBeneficiary = await sdk.getAirlockBeneficiary()
|
|
486
|
+
|
|
487
|
+
// Or build the entry manually if you do not have an SDK instance handy
|
|
488
|
+
// (airlockEntry will be equivalent to airlockBeneficiary above)
|
|
489
|
+
const owner = await getAirlockOwner(publicClient)
|
|
490
|
+
const airlockEntry = createAirlockBeneficiary(owner)
|
|
491
|
+
|
|
492
|
+
const migration = {
|
|
493
|
+
type: 'uniswapV4' as const,
|
|
494
|
+
fee: 3000,
|
|
495
|
+
tickSpacing: 60,
|
|
496
|
+
streamableFees: {
|
|
497
|
+
lockDuration: 365 * 24 * 60 * 60,
|
|
498
|
+
beneficiaries: [
|
|
499
|
+
airlockEntry, // or airlockBeneficiary
|
|
500
|
+
{ address: '0xYourDAO...', percentage: 9500 },
|
|
501
|
+
],
|
|
502
|
+
},
|
|
503
|
+
}
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
|
|
316
508
|
## Supported Chains
|
|
317
509
|
|
|
318
|
-
The SDK
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
510
|
+
The SDK exposes runtime constants and TypeScript types for supported chains:
|
|
511
|
+
|
|
512
|
+
```ts
|
|
513
|
+
import {
|
|
514
|
+
CHAIN_IDS,
|
|
515
|
+
SUPPORTED_CHAIN_IDS,
|
|
516
|
+
getAddresses,
|
|
517
|
+
isSupportedChainId,
|
|
518
|
+
type SupportedChainId,
|
|
519
|
+
type ChainAddresses,
|
|
520
|
+
} from '@whetstone-research/doppler-sdk'
|
|
521
|
+
|
|
522
|
+
// Validate and narrow a chain ID
|
|
523
|
+
function ensureSupported(id: number): SupportedChainId {
|
|
524
|
+
if (!isSupportedChainId(id)) throw new Error('Unsupported chain')
|
|
525
|
+
return id
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
const chainId = ensureSupported(CHAIN_IDS.BASE)
|
|
529
|
+
const addresses: ChainAddresses = getAddresses(chainId)
|
|
530
|
+
console.log('Airlock for Base:', addresses.airlock)
|
|
531
|
+
|
|
532
|
+
// Iterate supported chains
|
|
533
|
+
for (const id of SUPPORTED_CHAIN_IDS) {
|
|
534
|
+
console.log('Supported chain id:', id)
|
|
535
|
+
}
|
|
536
|
+
```
|
|
322
537
|
|
|
323
538
|
## Advanced Usage
|
|
324
539
|
|
|
@@ -363,6 +578,8 @@ class DopplerSDK {
|
|
|
363
578
|
// Methods
|
|
364
579
|
getStaticAuction(poolAddress: Address): Promise<StaticAuction>
|
|
365
580
|
getDynamicAuction(hookAddress: Address): Promise<DynamicAuction>
|
|
581
|
+
// Multicurve helper
|
|
582
|
+
buildMulticurveAuction(): MulticurveBuilder
|
|
366
583
|
getPoolInfo(poolAddress: Address): Promise<PoolInfo>
|
|
367
584
|
getHookInfo(hookAddress: Address): Promise<HookInfo>
|
|
368
585
|
}
|
|
@@ -376,6 +593,7 @@ Key types are exported for use in your applications:
|
|
|
376
593
|
import type {
|
|
377
594
|
CreateStaticAuctionParams,
|
|
378
595
|
CreateDynamicAuctionParams,
|
|
596
|
+
CreateMulticurveParams,
|
|
379
597
|
MigrationConfig,
|
|
380
598
|
PoolInfo,
|
|
381
599
|
HookInfo,
|
package/dist/DopplerSDK.d.mts
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
import { Address,
|
|
2
|
-
import { DopplerSDKConfig, PoolInfo, HookInfo } from './types.mjs';
|
|
1
|
+
import { Address, WalletClient } from 'viem';
|
|
2
|
+
import { DopplerSDKConfig, PoolInfo, HookInfo, SupportedPublicClient, BeneficiaryData } from './types.mjs';
|
|
3
|
+
import { SupportedChainId } from './addresses.mjs';
|
|
3
4
|
import { DopplerFactory } from './entities/DopplerFactory.mjs';
|
|
4
5
|
import { StaticAuction } from './entities/auction/StaticAuction.mjs';
|
|
5
6
|
import { DynamicAuction } from './entities/auction/DynamicAuction.mjs';
|
|
6
7
|
import { Quoter } from './entities/quoter/Quoter.mjs';
|
|
8
|
+
import { Derc20 } from './entities/token/derc20/Derc20.mjs';
|
|
9
|
+
import { StaticAuctionBuilder, DynamicAuctionBuilder, MulticurveBuilder } from './builders.mjs';
|
|
10
|
+
import 'viem/chains';
|
|
7
11
|
|
|
8
|
-
declare class DopplerSDK {
|
|
12
|
+
declare class DopplerSDK<C extends SupportedChainId = SupportedChainId> {
|
|
9
13
|
private publicClient;
|
|
10
14
|
private walletClient?;
|
|
11
|
-
|
|
15
|
+
chainId: C;
|
|
12
16
|
private _factory?;
|
|
13
17
|
private _quoter?;
|
|
14
18
|
constructor(config: DopplerSDKConfig);
|
|
15
19
|
/**
|
|
16
20
|
* Get the factory instance for creating auctions
|
|
17
21
|
*/
|
|
18
|
-
get factory(): DopplerFactory
|
|
22
|
+
get factory(): DopplerFactory<C>;
|
|
19
23
|
/**
|
|
20
24
|
* Get the quoter instance for price queries
|
|
21
25
|
*/
|
|
@@ -30,6 +34,11 @@ declare class DopplerSDK {
|
|
|
30
34
|
* @param hookAddress The address of the Uniswap V4 hook
|
|
31
35
|
*/
|
|
32
36
|
getDynamicAuction(hookAddress: Address): Promise<DynamicAuction>;
|
|
37
|
+
/**
|
|
38
|
+
* Get a DERC20 token instance for interacting with a token
|
|
39
|
+
* @param tokenAddress The address of the DERC20 token
|
|
40
|
+
*/
|
|
41
|
+
getDerc20(tokenAddress: Address): Derc20;
|
|
33
42
|
/**
|
|
34
43
|
* Get information about a static auction pool
|
|
35
44
|
* @param poolAddress The address of the pool
|
|
@@ -40,17 +49,37 @@ declare class DopplerSDK {
|
|
|
40
49
|
* @param hookAddress The address of the hook
|
|
41
50
|
*/
|
|
42
51
|
getHookInfo(hookAddress: Address): Promise<HookInfo>;
|
|
52
|
+
/**
|
|
53
|
+
* Create a new static auction builder
|
|
54
|
+
*/
|
|
55
|
+
buildStaticAuction(): StaticAuctionBuilder<C>;
|
|
56
|
+
/**
|
|
57
|
+
* Create a new dynamic auction builder
|
|
58
|
+
*/
|
|
59
|
+
buildDynamicAuction(): DynamicAuctionBuilder<C>;
|
|
60
|
+
/**
|
|
61
|
+
* Create a new multicurve (V4 initializer) auction builder
|
|
62
|
+
*/
|
|
63
|
+
buildMulticurveAuction(): MulticurveBuilder<C>;
|
|
43
64
|
/**
|
|
44
65
|
* Get the current chain ID
|
|
45
66
|
*/
|
|
46
|
-
getChainId():
|
|
67
|
+
getChainId(): C;
|
|
47
68
|
/**
|
|
48
69
|
* Get the underlying clients
|
|
49
70
|
*/
|
|
50
71
|
getClients(): {
|
|
51
|
-
publicClient:
|
|
72
|
+
publicClient: SupportedPublicClient;
|
|
52
73
|
walletClient?: WalletClient;
|
|
53
74
|
};
|
|
75
|
+
/**
|
|
76
|
+
* Get the airlock owner address for the configured chain
|
|
77
|
+
*/
|
|
78
|
+
getAirlockOwner(): Promise<Address>;
|
|
79
|
+
/**
|
|
80
|
+
* Convenience helper for building the airlock beneficiary entry with the default 5%
|
|
81
|
+
*/
|
|
82
|
+
getAirlockBeneficiary(percentage?: number): Promise<BeneficiaryData>;
|
|
54
83
|
}
|
|
55
84
|
|
|
56
85
|
export { DopplerSDK };
|
package/dist/DopplerSDK.d.ts
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
import { Address,
|
|
2
|
-
import { DopplerSDKConfig, PoolInfo, HookInfo } from './types.js';
|
|
1
|
+
import { Address, WalletClient } from 'viem';
|
|
2
|
+
import { DopplerSDKConfig, PoolInfo, HookInfo, SupportedPublicClient, BeneficiaryData } from './types.js';
|
|
3
|
+
import { SupportedChainId } from './addresses.js';
|
|
3
4
|
import { DopplerFactory } from './entities/DopplerFactory.js';
|
|
4
5
|
import { StaticAuction } from './entities/auction/StaticAuction.js';
|
|
5
6
|
import { DynamicAuction } from './entities/auction/DynamicAuction.js';
|
|
6
7
|
import { Quoter } from './entities/quoter/Quoter.js';
|
|
8
|
+
import { Derc20 } from './entities/token/derc20/Derc20.js';
|
|
9
|
+
import { StaticAuctionBuilder, DynamicAuctionBuilder, MulticurveBuilder } from './builders.js';
|
|
10
|
+
import 'viem/chains';
|
|
7
11
|
|
|
8
|
-
declare class DopplerSDK {
|
|
12
|
+
declare class DopplerSDK<C extends SupportedChainId = SupportedChainId> {
|
|
9
13
|
private publicClient;
|
|
10
14
|
private walletClient?;
|
|
11
|
-
|
|
15
|
+
chainId: C;
|
|
12
16
|
private _factory?;
|
|
13
17
|
private _quoter?;
|
|
14
18
|
constructor(config: DopplerSDKConfig);
|
|
15
19
|
/**
|
|
16
20
|
* Get the factory instance for creating auctions
|
|
17
21
|
*/
|
|
18
|
-
get factory(): DopplerFactory
|
|
22
|
+
get factory(): DopplerFactory<C>;
|
|
19
23
|
/**
|
|
20
24
|
* Get the quoter instance for price queries
|
|
21
25
|
*/
|
|
@@ -30,6 +34,11 @@ declare class DopplerSDK {
|
|
|
30
34
|
* @param hookAddress The address of the Uniswap V4 hook
|
|
31
35
|
*/
|
|
32
36
|
getDynamicAuction(hookAddress: Address): Promise<DynamicAuction>;
|
|
37
|
+
/**
|
|
38
|
+
* Get a DERC20 token instance for interacting with a token
|
|
39
|
+
* @param tokenAddress The address of the DERC20 token
|
|
40
|
+
*/
|
|
41
|
+
getDerc20(tokenAddress: Address): Derc20;
|
|
33
42
|
/**
|
|
34
43
|
* Get information about a static auction pool
|
|
35
44
|
* @param poolAddress The address of the pool
|
|
@@ -40,17 +49,37 @@ declare class DopplerSDK {
|
|
|
40
49
|
* @param hookAddress The address of the hook
|
|
41
50
|
*/
|
|
42
51
|
getHookInfo(hookAddress: Address): Promise<HookInfo>;
|
|
52
|
+
/**
|
|
53
|
+
* Create a new static auction builder
|
|
54
|
+
*/
|
|
55
|
+
buildStaticAuction(): StaticAuctionBuilder<C>;
|
|
56
|
+
/**
|
|
57
|
+
* Create a new dynamic auction builder
|
|
58
|
+
*/
|
|
59
|
+
buildDynamicAuction(): DynamicAuctionBuilder<C>;
|
|
60
|
+
/**
|
|
61
|
+
* Create a new multicurve (V4 initializer) auction builder
|
|
62
|
+
*/
|
|
63
|
+
buildMulticurveAuction(): MulticurveBuilder<C>;
|
|
43
64
|
/**
|
|
44
65
|
* Get the current chain ID
|
|
45
66
|
*/
|
|
46
|
-
getChainId():
|
|
67
|
+
getChainId(): C;
|
|
47
68
|
/**
|
|
48
69
|
* Get the underlying clients
|
|
49
70
|
*/
|
|
50
71
|
getClients(): {
|
|
51
|
-
publicClient:
|
|
72
|
+
publicClient: SupportedPublicClient;
|
|
52
73
|
walletClient?: WalletClient;
|
|
53
74
|
};
|
|
75
|
+
/**
|
|
76
|
+
* Get the airlock owner address for the configured chain
|
|
77
|
+
*/
|
|
78
|
+
getAirlockOwner(): Promise<Address>;
|
|
79
|
+
/**
|
|
80
|
+
* Convenience helper for building the airlock beneficiary entry with the default 5%
|
|
81
|
+
*/
|
|
82
|
+
getAirlockBeneficiary(percentage?: number): Promise<BeneficiaryData>;
|
|
54
83
|
}
|
|
55
84
|
|
|
56
85
|
export { DopplerSDK };
|
package/dist/DopplerSDK.js
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkXYBEODKJ_js = require('./chunk-XYBEODKJ.js');
|
|
4
4
|
require('./chunk-KRN3ROUE.js');
|
|
5
5
|
require('./chunk-P7CHGWY7.js');
|
|
6
|
-
require('./chunk-
|
|
7
|
-
require('./chunk-
|
|
8
|
-
require('./chunk-
|
|
9
|
-
require('./chunk-
|
|
10
|
-
require('./chunk-
|
|
11
|
-
require('./chunk-
|
|
12
|
-
require('./chunk-
|
|
13
|
-
require('./chunk-
|
|
14
|
-
require('./chunk-
|
|
6
|
+
require('./chunk-OVSI43QO.js');
|
|
7
|
+
require('./chunk-WQHTNL5L.js');
|
|
8
|
+
require('./chunk-X3UMAHOJ.js');
|
|
9
|
+
require('./chunk-C5EPBZOZ.js');
|
|
10
|
+
require('./chunk-VEIVYUYF.js');
|
|
11
|
+
require('./chunk-LS4TK6SX.js');
|
|
12
|
+
require('./chunk-73SOFTOX.js');
|
|
13
|
+
require('./chunk-V2DF2GUE.js');
|
|
14
|
+
require('./chunk-ITN5EO2T.js');
|
|
15
|
+
require('./chunk-4HM3ERBU.js');
|
|
16
|
+
require('./chunk-KPBCG4X2.js');
|
|
17
|
+
require('./chunk-XG7K4R56.js');
|
|
18
|
+
require('./chunk-EFTJVQHS.js');
|
|
19
|
+
require('./chunk-KMGO45KZ.js');
|
|
20
|
+
require('./chunk-Z7ZKBAUR.js');
|
|
21
|
+
require('./chunk-45OJGXN4.js');
|
|
22
|
+
require('./chunk-YSDTNI6S.js');
|
|
23
|
+
require('./chunk-E4OANJ7J.js');
|
|
24
|
+
require('./chunk-CIRZKWLL.js');
|
|
15
25
|
|
|
16
26
|
|
|
17
27
|
|
|
18
28
|
Object.defineProperty(exports, "DopplerSDK", {
|
|
19
29
|
enumerable: true,
|
|
20
|
-
get: function () { return
|
|
30
|
+
get: function () { return chunkXYBEODKJ_js.DopplerSDK; }
|
|
21
31
|
});
|
|
22
32
|
//# sourceMappingURL=DopplerSDK.js.map
|
|
23
33
|
//# sourceMappingURL=DopplerSDK.js.map
|
package/dist/DopplerSDK.mjs
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
export { DopplerSDK } from './chunk-
|
|
1
|
+
export { DopplerSDK } from './chunk-65BSFCKK.mjs';
|
|
2
2
|
import './chunk-AZLFJNTG.mjs';
|
|
3
3
|
import './chunk-QSQGLWNY.mjs';
|
|
4
|
-
import './chunk-
|
|
5
|
-
import './chunk-
|
|
6
|
-
import './chunk-
|
|
7
|
-
import './chunk-
|
|
8
|
-
import './chunk-
|
|
9
|
-
import './chunk-
|
|
10
|
-
import './chunk-
|
|
11
|
-
import './chunk-
|
|
12
|
-
import './chunk-
|
|
4
|
+
import './chunk-AINJQVZP.mjs';
|
|
5
|
+
import './chunk-FOESYJP3.mjs';
|
|
6
|
+
import './chunk-RV64M4Q6.mjs';
|
|
7
|
+
import './chunk-O2QILOKJ.mjs';
|
|
8
|
+
import './chunk-XNMXN5SZ.mjs';
|
|
9
|
+
import './chunk-PAPXGPJB.mjs';
|
|
10
|
+
import './chunk-44PYMMCH.mjs';
|
|
11
|
+
import './chunk-HGLO5LDS.mjs';
|
|
12
|
+
import './chunk-ADGPGPA3.mjs';
|
|
13
|
+
import './chunk-ECD4FV3A.mjs';
|
|
14
|
+
import './chunk-AYPP5JEQ.mjs';
|
|
15
|
+
import './chunk-4K5GBNQV.mjs';
|
|
16
|
+
import './chunk-WTKJ2OCS.mjs';
|
|
17
|
+
import './chunk-I5K7TMG3.mjs';
|
|
18
|
+
import './chunk-RAFSIZDB.mjs';
|
|
19
|
+
import './chunk-F7U377SD.mjs';
|
|
20
|
+
import './chunk-H6JN7KCJ.mjs';
|
|
21
|
+
import './chunk-YCLVZS7E.mjs';
|
|
22
|
+
import './chunk-7W72MFJO.mjs';
|
|
13
23
|
//# sourceMappingURL=DopplerSDK.mjs.map
|
|
14
24
|
//# sourceMappingURL=DopplerSDK.mjs.map
|