tempo.ts 0.7.5 → 0.8.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/CHANGELOG.md +32 -0
- package/dist/chains.d.ts +6 -20
- package/dist/chains.d.ts.map +1 -1
- package/dist/chains.js +14 -15
- package/dist/chains.js.map +1 -1
- package/dist/ox/KeyAuthorization.d.ts +356 -0
- package/dist/ox/KeyAuthorization.d.ts.map +1 -0
- package/dist/ox/KeyAuthorization.js +360 -0
- package/dist/ox/KeyAuthorization.js.map +1 -0
- package/dist/ox/SignatureEnvelope.d.ts +21 -6
- package/dist/ox/SignatureEnvelope.d.ts.map +1 -1
- package/dist/ox/SignatureEnvelope.js +43 -3
- package/dist/ox/SignatureEnvelope.js.map +1 -1
- package/dist/ox/Transaction.d.ts +5 -1
- package/dist/ox/Transaction.d.ts.map +1 -1
- package/dist/ox/Transaction.js +5 -0
- package/dist/ox/Transaction.js.map +1 -1
- package/dist/ox/TransactionEnvelopeAA.d.ts +9 -0
- package/dist/ox/TransactionEnvelopeAA.d.ts.map +1 -1
- package/dist/ox/TransactionEnvelopeAA.js +17 -4
- package/dist/ox/TransactionEnvelopeAA.js.map +1 -1
- package/dist/ox/TransactionRequest.d.ts +7 -1
- package/dist/ox/TransactionRequest.d.ts.map +1 -1
- package/dist/ox/TransactionRequest.js +12 -0
- package/dist/ox/TransactionRequest.js.map +1 -1
- package/dist/ox/index.d.ts +1 -0
- package/dist/ox/index.d.ts.map +1 -1
- package/dist/ox/index.js +1 -0
- package/dist/ox/index.js.map +1 -1
- package/dist/prool/Instance.js +1 -1
- package/dist/prool/Instance.js.map +1 -1
- package/{src/prool/internal → dist/prool}/chain.json +4 -2
- package/dist/viem/Abis.d.ts +319 -6
- package/dist/viem/Abis.d.ts.map +1 -1
- package/dist/viem/Abis.js +199 -7
- package/dist/viem/Abis.js.map +1 -1
- package/dist/viem/Account.d.ts +103 -14
- package/dist/viem/Account.d.ts.map +1 -1
- package/dist/viem/Account.js +177 -23
- package/dist/viem/Account.js.map +1 -1
- package/dist/viem/Actions/account.d.ts.map +1 -1
- package/dist/viem/Actions/account.js +4 -5
- package/dist/viem/Actions/account.js.map +1 -1
- package/dist/viem/Actions/amm.d.ts +84 -32
- package/dist/viem/Actions/amm.d.ts.map +1 -1
- package/dist/viem/Actions/amm.js +12 -32
- package/dist/viem/Actions/amm.js.map +1 -1
- package/dist/viem/Actions/dex.d.ts +156 -4
- package/dist/viem/Actions/dex.d.ts.map +1 -1
- package/dist/viem/Actions/fee.d.ts +4 -0
- package/dist/viem/Actions/fee.d.ts.map +1 -1
- package/dist/viem/Actions/reward.d.ts +78 -0
- package/dist/viem/Actions/reward.d.ts.map +1 -1
- package/dist/viem/Actions/token.d.ts +585 -0
- package/dist/viem/Actions/token.d.ts.map +1 -1
- package/dist/viem/Actions/token.js +2 -2
- package/dist/viem/Actions/token.js.map +1 -1
- package/dist/viem/Addresses.d.ts +1 -1
- package/dist/viem/Addresses.d.ts.map +1 -1
- package/dist/viem/Addresses.js +1 -1
- package/dist/viem/Addresses.js.map +1 -1
- package/dist/viem/Chain.d.ts +35 -0
- package/dist/viem/Chain.d.ts.map +1 -1
- package/dist/viem/Chain.js +37 -0
- package/dist/viem/Chain.js.map +1 -1
- package/dist/viem/Decorator.d.ts +193 -16
- package/dist/viem/Decorator.d.ts.map +1 -1
- package/dist/viem/Decorator.js +7 -0
- package/dist/viem/Decorator.js.map +1 -1
- package/dist/viem/Formatters.d.ts.map +1 -1
- package/dist/viem/Formatters.js +8 -7
- package/dist/viem/Formatters.js.map +1 -1
- package/dist/viem/Storage.d.ts +1 -0
- package/dist/viem/Storage.d.ts.map +1 -1
- package/dist/viem/Storage.js +21 -0
- package/dist/viem/Storage.js.map +1 -1
- package/dist/viem/TokenIds.d.ts +1 -1
- package/dist/viem/TokenIds.d.ts.map +1 -1
- package/dist/viem/TokenIds.js +1 -1
- package/dist/viem/TokenIds.js.map +1 -1
- package/dist/viem/Transaction.d.ts +9 -1
- package/dist/viem/Transaction.d.ts.map +1 -1
- package/dist/viem/Transaction.js +2 -1
- package/dist/viem/Transaction.js.map +1 -1
- package/dist/viem/WebAuthnP256.d.ts +4 -1
- package/dist/viem/WebAuthnP256.d.ts.map +1 -1
- package/dist/viem/WebAuthnP256.js +3 -1
- package/dist/viem/WebAuthnP256.js.map +1 -1
- package/dist/wagmi/Actions/amm.d.ts +6 -16
- package/dist/wagmi/Actions/amm.d.ts.map +1 -1
- package/dist/wagmi/Actions/amm.js +6 -16
- package/dist/wagmi/Actions/amm.js.map +1 -1
- package/dist/wagmi/Connector.d.ts +25 -8
- package/dist/wagmi/Connector.d.ts.map +1 -1
- package/dist/wagmi/Connector.js +120 -27
- package/dist/wagmi/Connector.js.map +1 -1
- package/dist/wagmi/Hooks/amm.d.ts +6 -16
- package/dist/wagmi/Hooks/amm.d.ts.map +1 -1
- package/dist/wagmi/Hooks/amm.js +6 -16
- package/dist/wagmi/Hooks/amm.js.map +1 -1
- package/package.json +3 -2
- package/src/chains.ts +14 -15
- package/src/ox/KeyAuthorization.test.ts +1332 -0
- package/src/ox/KeyAuthorization.ts +542 -0
- package/src/ox/SignatureEnvelope.test.ts +624 -0
- package/src/ox/SignatureEnvelope.ts +89 -9
- package/src/ox/Transaction.test.ts +214 -0
- package/src/ox/Transaction.ts +13 -1
- package/src/ox/TransactionEnvelopeAA.test.ts +164 -4
- package/src/ox/TransactionEnvelopeAA.ts +36 -3
- package/src/ox/TransactionRequest.ts +22 -1
- package/src/ox/e2e.test.ts +612 -5
- package/src/ox/index.ts +1 -0
- package/src/prool/Instance.ts +1 -1
- package/src/prool/chain.json +238 -0
- package/src/server/Handler.test.ts +20 -36
- package/src/viem/Abis.ts +200 -7
- package/src/viem/Account.test.ts +444 -0
- package/src/viem/Account.ts +355 -42
- package/src/viem/Actions/account.ts +3 -5
- package/src/viem/Actions/amm.test.ts +220 -1
- package/src/viem/Actions/amm.ts +12 -32
- package/src/viem/Actions/token.test.ts +8 -8
- package/src/viem/Actions/token.ts +2 -2
- package/src/viem/Addresses.ts +1 -1
- package/src/viem/Chain.test.ts +168 -0
- package/src/viem/Chain.ts +37 -1
- package/src/viem/Decorator.ts +214 -16
- package/src/viem/Formatters.ts +8 -7
- package/src/viem/Storage.ts +22 -0
- package/src/viem/TokenIds.ts +1 -1
- package/src/viem/Transaction.ts +14 -2
- package/src/viem/WebAuthnP256.ts +8 -2
- package/src/viem/e2e.test.ts +299 -96
- package/src/wagmi/Actions/amm.test.ts +93 -2
- package/src/wagmi/Actions/amm.ts +6 -16
- package/src/wagmi/Connector.test.ts +1 -1
- package/src/wagmi/Connector.ts +184 -54
- package/src/wagmi/Hooks/amm.test.ts +335 -0
- package/src/wagmi/Hooks/amm.ts +6 -16
- package/src/wagmi/Hooks/fee.test.ts +10 -4
- package/src/wagmi/Hooks/token.test.ts +0 -488
- package/dist/viem/internal/account.d.ts +0 -21
- package/dist/viem/internal/account.d.ts.map +0 -1
- package/dist/viem/internal/account.js +0 -61
- package/dist/viem/internal/account.js.map +0 -1
- package/src/viem/internal/account.ts +0 -89
|
@@ -3,9 +3,14 @@ import { Abis, Actions } from 'tempo.ts/viem'
|
|
|
3
3
|
import { parseUnits } from 'viem'
|
|
4
4
|
import { writeContractSync } from 'viem/actions'
|
|
5
5
|
import { describe, expect, test } from 'vitest'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
accounts,
|
|
8
|
+
clientWithAccount,
|
|
9
|
+
setupPoolWithLiquidity,
|
|
10
|
+
} from '../../../test/viem/config.js'
|
|
7
11
|
|
|
8
12
|
const account = accounts[0]
|
|
13
|
+
const account2 = accounts[1]
|
|
9
14
|
|
|
10
15
|
describe('getPool', () => {
|
|
11
16
|
test('default', async () => {
|
|
@@ -102,6 +107,173 @@ describe('mint', () => {
|
|
|
102
107
|
})
|
|
103
108
|
})
|
|
104
109
|
|
|
110
|
+
describe.skip('burn', () => {
|
|
111
|
+
test('default', async () => {
|
|
112
|
+
const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
|
|
113
|
+
|
|
114
|
+
// Get LP balance before burn
|
|
115
|
+
const lpBalanceBefore = await Actions.amm.getLiquidityBalance(
|
|
116
|
+
clientWithAccount,
|
|
117
|
+
{
|
|
118
|
+
address: account.address,
|
|
119
|
+
userToken: tokenAddress,
|
|
120
|
+
validatorToken: 1n,
|
|
121
|
+
},
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
// TODO(TEMPO-1183): Remove this janky fix to get some user token in the pool
|
|
125
|
+
await Actions.token.transferSync(clientWithAccount, {
|
|
126
|
+
to: '0x30D861999070Ae03B9548501DBd573E11A9f59Ee',
|
|
127
|
+
amount: 600n,
|
|
128
|
+
token: tokenAddress,
|
|
129
|
+
feeToken: tokenAddress,
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
// Burn half of LP tokens
|
|
133
|
+
const {
|
|
134
|
+
receipt: burnReceipt,
|
|
135
|
+
userToken,
|
|
136
|
+
...burnResult
|
|
137
|
+
} = await Actions.amm.burnSync(clientWithAccount, {
|
|
138
|
+
userToken: tokenAddress,
|
|
139
|
+
validatorToken: 1n,
|
|
140
|
+
liquidity: lpBalanceBefore / 2n,
|
|
141
|
+
to: account2.address,
|
|
142
|
+
})
|
|
143
|
+
const { sender, to, ...rest } = burnResult
|
|
144
|
+
|
|
145
|
+
expect(burnReceipt).toBeDefined()
|
|
146
|
+
expect(userToken).toBe(tokenAddress)
|
|
147
|
+
expect(sender).toBe(account.address)
|
|
148
|
+
expect(to).toBe(account2.address)
|
|
149
|
+
expect(rest).toMatchInlineSnapshot(`
|
|
150
|
+
{
|
|
151
|
+
"amountUserToken": 337n,
|
|
152
|
+
"amountValidatorToken": 49998664n,
|
|
153
|
+
"liquidity": 24999500n,
|
|
154
|
+
"validatorToken": "0x20C0000000000000000000000000000000000001",
|
|
155
|
+
}
|
|
156
|
+
`)
|
|
157
|
+
|
|
158
|
+
// Verify LP balance decreased
|
|
159
|
+
const lpBalanceAfter = await Actions.amm.getLiquidityBalance(
|
|
160
|
+
clientWithAccount,
|
|
161
|
+
{
|
|
162
|
+
address: account.address,
|
|
163
|
+
userToken: tokenAddress,
|
|
164
|
+
validatorToken: 1n,
|
|
165
|
+
},
|
|
166
|
+
)
|
|
167
|
+
expect(lpBalanceAfter).toBeLessThan(lpBalanceBefore)
|
|
168
|
+
expect(lpBalanceAfter).toBe(lpBalanceBefore / 2n)
|
|
169
|
+
|
|
170
|
+
// Verify pool reserves decreased
|
|
171
|
+
const pool = await Actions.amm.getPool(clientWithAccount, {
|
|
172
|
+
userToken: tokenAddress,
|
|
173
|
+
validatorToken: 1n,
|
|
174
|
+
})
|
|
175
|
+
expect(pool).toMatchInlineSnapshot(`
|
|
176
|
+
{
|
|
177
|
+
"reserveUserToken": 338n,
|
|
178
|
+
"reserveValidatorToken": 50000664n,
|
|
179
|
+
"totalSupply": 25000500n,
|
|
180
|
+
}
|
|
181
|
+
`)
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
describe.skip('rebalanceSwap', () => {
|
|
186
|
+
test('default', async () => {
|
|
187
|
+
const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
|
|
188
|
+
|
|
189
|
+
// TODO(TEMPO-1183): Remove this janky fix to get some user token in the pool
|
|
190
|
+
await Actions.token.transferSync(clientWithAccount, {
|
|
191
|
+
to: '0x30D861999070Ae03B9548501DBd573E11A9f59Ee',
|
|
192
|
+
amount: 600n,
|
|
193
|
+
token: tokenAddress,
|
|
194
|
+
feeToken: tokenAddress,
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
// Get balance before swap
|
|
198
|
+
const balanceBefore = await Actions.token.getBalance(clientWithAccount, {
|
|
199
|
+
token: tokenAddress,
|
|
200
|
+
account: account2.address,
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
// Perform rebalance swap
|
|
204
|
+
const {
|
|
205
|
+
receipt: swapReceipt,
|
|
206
|
+
swapper,
|
|
207
|
+
userToken,
|
|
208
|
+
...swapResult
|
|
209
|
+
} = await Actions.amm.rebalanceSwapSync(clientWithAccount, {
|
|
210
|
+
userToken: tokenAddress,
|
|
211
|
+
validatorToken: 1n,
|
|
212
|
+
amountOut: 100n,
|
|
213
|
+
to: account2.address,
|
|
214
|
+
account: account,
|
|
215
|
+
})
|
|
216
|
+
expect(swapReceipt).toBeDefined()
|
|
217
|
+
expect(userToken).toBe(tokenAddress)
|
|
218
|
+
expect(swapper).toBe(account.address)
|
|
219
|
+
expect(swapResult).toMatchInlineSnapshot(`
|
|
220
|
+
{
|
|
221
|
+
"amountIn": 100n,
|
|
222
|
+
"amountOut": 100n,
|
|
223
|
+
"validatorToken": "0x20C0000000000000000000000000000000000001",
|
|
224
|
+
}
|
|
225
|
+
`)
|
|
226
|
+
|
|
227
|
+
// Verify balance increased
|
|
228
|
+
const balanceAfter = await Actions.token.getBalance(clientWithAccount, {
|
|
229
|
+
token: tokenAddress,
|
|
230
|
+
account: account2.address,
|
|
231
|
+
})
|
|
232
|
+
expect(balanceAfter).toBe(balanceBefore + 100n)
|
|
233
|
+
})
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
describe.skip('watchRebalanceSwap', () => {
|
|
237
|
+
test('default', async () => {
|
|
238
|
+
const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
|
|
239
|
+
|
|
240
|
+
// TODO(TEMPO-1183): Remove this janky fix to get some user token in the pool
|
|
241
|
+
await Actions.token.transferSync(clientWithAccount, {
|
|
242
|
+
to: '0x30D861999070Ae03B9548501DBd573E11A9f59Ee',
|
|
243
|
+
amount: 600n,
|
|
244
|
+
token: tokenAddress,
|
|
245
|
+
feeToken: tokenAddress,
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
let eventArgs: any = null
|
|
249
|
+
const unwatch = Actions.amm.watchRebalanceSwap(clientWithAccount, {
|
|
250
|
+
onRebalanceSwap: (args) => {
|
|
251
|
+
eventArgs = args
|
|
252
|
+
},
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
// Perform rebalance swap
|
|
256
|
+
await Actions.amm.rebalanceSwapSync(clientWithAccount, {
|
|
257
|
+
userToken: tokenAddress,
|
|
258
|
+
validatorToken: 1n,
|
|
259
|
+
amountOut: 100n,
|
|
260
|
+
to: account2.address,
|
|
261
|
+
account: account,
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
await setTimeout(1000)
|
|
265
|
+
|
|
266
|
+
expect(eventArgs).toBeDefined()
|
|
267
|
+
expect(eventArgs.userToken.toLowerCase()).toBe(tokenAddress.toLowerCase())
|
|
268
|
+
expect(eventArgs.validatorToken.toLowerCase()).toBe(
|
|
269
|
+
'0x20c0000000000000000000000000000000000001',
|
|
270
|
+
)
|
|
271
|
+
expect(eventArgs.amountOut).toBe(100n)
|
|
272
|
+
|
|
273
|
+
unwatch()
|
|
274
|
+
})
|
|
275
|
+
})
|
|
276
|
+
|
|
105
277
|
describe('watchMint', () => {
|
|
106
278
|
test('default', async () => {
|
|
107
279
|
// Create a new token for testing
|
|
@@ -160,3 +332,50 @@ describe('watchMint', () => {
|
|
|
160
332
|
unwatch()
|
|
161
333
|
})
|
|
162
334
|
})
|
|
335
|
+
|
|
336
|
+
describe.skip('watchBurn', () => {
|
|
337
|
+
test('default', async () => {
|
|
338
|
+
const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount)
|
|
339
|
+
|
|
340
|
+
// Get LP balance
|
|
341
|
+
const lpBalance = await Actions.amm.getLiquidityBalance(clientWithAccount, {
|
|
342
|
+
userToken: tokenAddress,
|
|
343
|
+
validatorToken: 1n,
|
|
344
|
+
address: account.address,
|
|
345
|
+
})
|
|
346
|
+
|
|
347
|
+
// TODO(TEMPO-1183): Remove this janky fix to get some user token in the pool
|
|
348
|
+
await Actions.token.transferSync(clientWithAccount, {
|
|
349
|
+
to: '0x30D861999070Ae03B9548501DBd573E11A9f59Ee',
|
|
350
|
+
amount: 600n,
|
|
351
|
+
token: tokenAddress,
|
|
352
|
+
feeToken: tokenAddress,
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
let eventArgs: any = null
|
|
356
|
+
const unwatch = Actions.amm.watchBurn(clientWithAccount, {
|
|
357
|
+
onBurn: (args) => {
|
|
358
|
+
eventArgs = args
|
|
359
|
+
},
|
|
360
|
+
})
|
|
361
|
+
|
|
362
|
+
// Burn LP tokens
|
|
363
|
+
await Actions.amm.burnSync(clientWithAccount, {
|
|
364
|
+
userToken: tokenAddress,
|
|
365
|
+
validatorToken: 1n,
|
|
366
|
+
liquidity: lpBalance / 2n,
|
|
367
|
+
to: account.address,
|
|
368
|
+
})
|
|
369
|
+
|
|
370
|
+
await setTimeout(1000)
|
|
371
|
+
|
|
372
|
+
expect(eventArgs).toBeDefined()
|
|
373
|
+
expect(eventArgs.userToken.toLowerCase()).toBe(tokenAddress.toLowerCase())
|
|
374
|
+
expect(eventArgs.validatorToken.toLowerCase()).toBe(
|
|
375
|
+
'0x20c0000000000000000000000000000000000001',
|
|
376
|
+
)
|
|
377
|
+
expect(eventArgs.liquidity).toBe(lpBalance / 2n)
|
|
378
|
+
|
|
379
|
+
unwatch()
|
|
380
|
+
})
|
|
381
|
+
})
|
package/src/viem/Actions/amm.ts
CHANGED
|
@@ -456,14 +456,9 @@ export namespace rebalanceSwapSync {
|
|
|
456
456
|
* })
|
|
457
457
|
*
|
|
458
458
|
* const hash = await Actions.amm.mint(client, {
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
* },
|
|
463
|
-
* validatorToken: {
|
|
464
|
-
* address: '0x20c0...babe',
|
|
465
|
-
* amount: 100n,
|
|
466
|
-
* },
|
|
459
|
+
* userTokenAddress: '0x20c0...beef',
|
|
460
|
+
* validatorTokenAddress: '0x20c0...babe',
|
|
461
|
+
* validatorTokenAmount: 100n,
|
|
467
462
|
* to: '0xfeed...fede',
|
|
468
463
|
* })
|
|
469
464
|
* ```
|
|
@@ -552,25 +547,15 @@ export namespace mint {
|
|
|
552
547
|
* const { result } = await client.sendCalls({
|
|
553
548
|
* calls: [
|
|
554
549
|
* actions.amm.mint.call({
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
*
|
|
558
|
-
* },
|
|
559
|
-
* validatorToken: {
|
|
560
|
-
* address: '0x20c0...babe',
|
|
561
|
-
* amount: 100n,
|
|
562
|
-
* },
|
|
550
|
+
* userTokenAddress: '0x20c0...beef',
|
|
551
|
+
* validatorTokenAddress: '0x20c0...babe',
|
|
552
|
+
* validatorTokenAmount: 100n,
|
|
563
553
|
* to: '0xfeed...fede',
|
|
564
554
|
* }),
|
|
565
555
|
* actions.amm.mint.call({
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
* },
|
|
570
|
-
* validatorToken: {
|
|
571
|
-
* address: '0x20c0...babe',
|
|
572
|
-
* amount: 100n,
|
|
573
|
-
* },
|
|
556
|
+
* userTokenAddress: '0x20c0...babe',
|
|
557
|
+
* validatorTokenAddress: '0x20c0...babe',
|
|
558
|
+
* validatorTokenAmount: 100n,
|
|
574
559
|
* to: '0xfeed...fede',
|
|
575
560
|
* }),
|
|
576
561
|
* ]
|
|
@@ -635,14 +620,9 @@ export namespace mint {
|
|
|
635
620
|
* })
|
|
636
621
|
*
|
|
637
622
|
* const hash = await Actions.amm.mint(client, {
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
* },
|
|
642
|
-
* validatorToken: {
|
|
643
|
-
* address: '0x20c0...babe',
|
|
644
|
-
* amount: 100n,
|
|
645
|
-
* },
|
|
623
|
+
* userTokenAddress: '0x20c0...beef',
|
|
624
|
+
* validatorTokenAddress: '0x20c0...babe',
|
|
625
|
+
* validatorTokenAmount: 100n,
|
|
646
626
|
* to: '0xfeed...fede',
|
|
647
627
|
* })
|
|
648
628
|
* ```
|
|
@@ -349,7 +349,7 @@ describe('getMetadata', () => {
|
|
|
349
349
|
"name": "Test USD",
|
|
350
350
|
"paused": false,
|
|
351
351
|
"quoteToken": "0x20C0000000000000000000000000000000000000",
|
|
352
|
-
"supplyCap":
|
|
352
|
+
"supplyCap": 340282366920938463463374607431768211455n,
|
|
353
353
|
"symbol": "TUSD",
|
|
354
354
|
"totalSupply": 0n,
|
|
355
355
|
"transferPolicyId": 1n,
|
|
@@ -360,15 +360,15 @@ describe('getMetadata', () => {
|
|
|
360
360
|
test('behavior: quote token', async () => {
|
|
361
361
|
{
|
|
362
362
|
const metadata = await actions.token.getMetadata(clientWithAccount, {
|
|
363
|
-
token: TokenIds.
|
|
363
|
+
token: TokenIds.pathUsd,
|
|
364
364
|
})
|
|
365
365
|
|
|
366
366
|
expect(metadata).toMatchInlineSnapshot(`
|
|
367
367
|
{
|
|
368
368
|
"currency": "USD",
|
|
369
369
|
"decimals": 6,
|
|
370
|
-
"name": "
|
|
371
|
-
"symbol": "
|
|
370
|
+
"name": "pathUSD",
|
|
371
|
+
"symbol": "pathUSD",
|
|
372
372
|
"totalSupply": 18446744073709551615n,
|
|
373
373
|
}
|
|
374
374
|
`)
|
|
@@ -376,15 +376,15 @@ describe('getMetadata', () => {
|
|
|
376
376
|
|
|
377
377
|
{
|
|
378
378
|
const metadata = await actions.token.getMetadata(clientWithAccount, {
|
|
379
|
-
token: Addresses.
|
|
379
|
+
token: Addresses.pathUsd,
|
|
380
380
|
})
|
|
381
381
|
|
|
382
382
|
expect(metadata).toMatchInlineSnapshot(`
|
|
383
383
|
{
|
|
384
384
|
"currency": "USD",
|
|
385
385
|
"decimals": 6,
|
|
386
|
-
"name": "
|
|
387
|
-
"symbol": "
|
|
386
|
+
"name": "pathUSD",
|
|
387
|
+
"symbol": "pathUSD",
|
|
388
388
|
"totalSupply": 18446744073709551615n,
|
|
389
389
|
}
|
|
390
390
|
`)
|
|
@@ -409,7 +409,7 @@ describe('getMetadata', () => {
|
|
|
409
409
|
"name": "Test USD",
|
|
410
410
|
"paused": false,
|
|
411
411
|
"quoteToken": "0x20C0000000000000000000000000000000000000",
|
|
412
|
-
"supplyCap":
|
|
412
|
+
"supplyCap": 340282366920938463463374607431768211455n,
|
|
413
413
|
"symbol": "TUSD",
|
|
414
414
|
"totalSupply": 0n,
|
|
415
415
|
"transferPolicyId": 1n,
|
|
@@ -998,7 +998,7 @@ export namespace create {
|
|
|
998
998
|
name,
|
|
999
999
|
symbol,
|
|
1000
1000
|
currency,
|
|
1001
|
-
quoteToken = Addresses.
|
|
1001
|
+
quoteToken = Addresses.pathUsd,
|
|
1002
1002
|
admin,
|
|
1003
1003
|
} = args
|
|
1004
1004
|
return defineCall({
|
|
@@ -1285,7 +1285,7 @@ export async function getMetadata<chain extends Chain | undefined>(
|
|
|
1285
1285
|
const address = TokenId.toAddress(token)
|
|
1286
1286
|
const abi = Abis.tip20
|
|
1287
1287
|
|
|
1288
|
-
if (TokenId.from(token) === TokenId.fromAddress(Addresses.
|
|
1288
|
+
if (TokenId.from(token) === TokenId.fromAddress(Addresses.pathUsd))
|
|
1289
1289
|
return multicall(client, {
|
|
1290
1290
|
...rest,
|
|
1291
1291
|
contracts: [
|
package/src/viem/Addresses.ts
CHANGED
|
@@ -2,7 +2,7 @@ export const accountImplementation =
|
|
|
2
2
|
'0x7702c00000000000000000000000000000000000'
|
|
3
3
|
export const accountRegistrar = '0x7702ac0000000000000000000000000000000000'
|
|
4
4
|
export const feeManager = '0xfeec000000000000000000000000000000000000'
|
|
5
|
-
export const
|
|
5
|
+
export const pathUsd = '0x20c0000000000000000000000000000000000000'
|
|
6
6
|
export const stablecoinExchange = '0xdec0000000000000000000000000000000000000'
|
|
7
7
|
export const tip20Factory = '0x20fc000000000000000000000000000000000000'
|
|
8
8
|
export const tip403Registry = '0x403c000000000000000000000000000000000000'
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getTransaction,
|
|
3
|
+
prepareTransactionRequest,
|
|
4
|
+
sendTransactionSync,
|
|
5
|
+
} from 'viem/actions'
|
|
6
|
+
import { describe, expect, test, vi } from 'vitest'
|
|
7
|
+
import { chain, client, clientWithAccount } from '../../test/viem/config.js'
|
|
8
|
+
|
|
9
|
+
describe('chain.prepareTransactionRequest', () => {
|
|
10
|
+
test('behavior: sequential nonce keys for feePayer transactions', async () => {
|
|
11
|
+
const requests = await Promise.all([
|
|
12
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
13
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
14
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
15
|
+
])
|
|
16
|
+
|
|
17
|
+
expect((requests[0] as any)?.nonceKey).toBe(0n)
|
|
18
|
+
expect((requests[1] as any)?.nonceKey).toBeGreaterThan(0n)
|
|
19
|
+
expect((requests[2] as any)?.nonceKey).toBeGreaterThan(0n)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('behavior: nonce key counter resets after event loop tick', async () => {
|
|
23
|
+
const requests1 = await Promise.all([
|
|
24
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
25
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
26
|
+
])
|
|
27
|
+
|
|
28
|
+
expect((requests1[0] as any)?.nonceKey).toBe(0n)
|
|
29
|
+
expect((requests1[1] as any)?.nonceKey).toBeGreaterThan(0n)
|
|
30
|
+
|
|
31
|
+
// Wait for microtask queue to flush
|
|
32
|
+
await new Promise((resolve) => queueMicrotask(() => resolve(undefined)))
|
|
33
|
+
|
|
34
|
+
const requests2 = await Promise.all([
|
|
35
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
36
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
37
|
+
])
|
|
38
|
+
|
|
39
|
+
// Counter should have reset
|
|
40
|
+
expect((requests2[0] as any)?.nonceKey).toBe(0n)
|
|
41
|
+
expect((requests2[1] as any)?.nonceKey).toBeGreaterThan(0n)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('behavior: explicit nonceKey overrides counter', async () => {
|
|
45
|
+
const requests = await Promise.all([
|
|
46
|
+
chain.prepareTransactionRequest({
|
|
47
|
+
feePayer: true,
|
|
48
|
+
nonceKey: 42n,
|
|
49
|
+
} as never),
|
|
50
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
51
|
+
chain.prepareTransactionRequest({
|
|
52
|
+
feePayer: true,
|
|
53
|
+
nonceKey: 100n,
|
|
54
|
+
} as never),
|
|
55
|
+
])
|
|
56
|
+
|
|
57
|
+
expect((requests[0] as any)?.nonceKey).toBe(42n)
|
|
58
|
+
expect((requests[1] as any)?.nonceKey).toBe(0n)
|
|
59
|
+
expect((requests[2] as any)?.nonceKey).toBe(100n)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test('behavior: default nonceKey when feePayer is not true', async () => {
|
|
63
|
+
const request = await chain.prepareTransactionRequest({} as never)
|
|
64
|
+
expect((request as any)?.nonceKey).toBe(0n)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('behavior: nonce with sequential nonceKey', async () => {
|
|
68
|
+
const requests = await Promise.all([
|
|
69
|
+
chain.prepareTransactionRequest({ feePayer: true } as never), // nonceKey: 0n
|
|
70
|
+
chain.prepareTransactionRequest({ feePayer: true } as never), // nonceKey: 1n
|
|
71
|
+
chain.prepareTransactionRequest({ feePayer: true } as never), // nonceKey: 2n
|
|
72
|
+
])
|
|
73
|
+
|
|
74
|
+
// Note: 0n is falsy, so first request has nonce undefined
|
|
75
|
+
expect((requests[0] as any)?.nonce).toBe(undefined)
|
|
76
|
+
expect((requests[0] as any)?.nonceKey).toBe(0n)
|
|
77
|
+
|
|
78
|
+
// nonceKey >= 1n is truthy, so nonce is 0
|
|
79
|
+
expect((requests[1] as any)?.nonce).toBe(0)
|
|
80
|
+
expect((requests[1] as any)?.nonceKey).toBeGreaterThan(0n)
|
|
81
|
+
|
|
82
|
+
expect((requests[2] as any)?.nonce).toBe(0)
|
|
83
|
+
expect((requests[2] as any)?.nonceKey).toBeGreaterThan(0n)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
test('behavior: explicit nonce is preserved', async () => {
|
|
87
|
+
const request = await chain.prepareTransactionRequest({
|
|
88
|
+
feePayer: true,
|
|
89
|
+
nonce: 123,
|
|
90
|
+
} as never)
|
|
91
|
+
expect((request as any)?.nonce).toBe(123)
|
|
92
|
+
expect((request as any)?.nonceKey).toBe(0n)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test('behavior: default nonceKey is 0n (falsy)', async () => {
|
|
96
|
+
const request = await chain.prepareTransactionRequest({} as never)
|
|
97
|
+
expect((request as any)?.nonceKey).toBe(0n)
|
|
98
|
+
expect((request as any)?.nonce).toBe(undefined)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
test('behavior: resetScheduled optimization - only one microtask scheduled', async () => {
|
|
102
|
+
const queueMicrotaskSpy = vi.spyOn(globalThis, 'queueMicrotask')
|
|
103
|
+
const callCountBefore = queueMicrotaskSpy.mock.calls.length
|
|
104
|
+
|
|
105
|
+
// Prepare multiple transactions in parallel
|
|
106
|
+
await Promise.all([
|
|
107
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
108
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
109
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
110
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
111
|
+
chain.prepareTransactionRequest({ feePayer: true } as never),
|
|
112
|
+
])
|
|
113
|
+
|
|
114
|
+
const callCountAfter = queueMicrotaskSpy.mock.calls.length
|
|
115
|
+
|
|
116
|
+
// Only one microtask should have been scheduled for the reset
|
|
117
|
+
expect(callCountAfter - callCountBefore).toBe(1)
|
|
118
|
+
|
|
119
|
+
queueMicrotaskSpy.mockRestore()
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
describe('e2e', async () => {
|
|
123
|
+
test('behavior: prepareTransactionRequest', async () => {
|
|
124
|
+
const [request, request2, request3] = await Promise.all([
|
|
125
|
+
prepareTransactionRequest(client, {
|
|
126
|
+
to: '0x0000000000000000000000000000000000000000',
|
|
127
|
+
}),
|
|
128
|
+
prepareTransactionRequest(client, {
|
|
129
|
+
to: '0x0000000000000000000000000000000000000000',
|
|
130
|
+
}),
|
|
131
|
+
prepareTransactionRequest(client, {
|
|
132
|
+
to: '0x0000000000000000000000000000000000000000',
|
|
133
|
+
}),
|
|
134
|
+
])
|
|
135
|
+
expect(request.nonceKey).toBe(0n)
|
|
136
|
+
expect(request2.nonceKey).toBeGreaterThan(0n)
|
|
137
|
+
expect(request3.nonceKey).toBeGreaterThan(0n)
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
test('behavior: sendTransaction', async () => {
|
|
141
|
+
const receipts = await Promise.all([
|
|
142
|
+
sendTransactionSync(clientWithAccount, {
|
|
143
|
+
to: '0x0000000000000000000000000000000000000000',
|
|
144
|
+
}),
|
|
145
|
+
sendTransactionSync(clientWithAccount, {
|
|
146
|
+
to: '0x0000000000000000000000000000000000000001',
|
|
147
|
+
}),
|
|
148
|
+
sendTransactionSync(clientWithAccount, {
|
|
149
|
+
to: '0x0000000000000000000000000000000000000002',
|
|
150
|
+
}),
|
|
151
|
+
])
|
|
152
|
+
const transactions = await Promise.all([
|
|
153
|
+
getTransaction(clientWithAccount, {
|
|
154
|
+
hash: receipts[0].transactionHash,
|
|
155
|
+
}),
|
|
156
|
+
getTransaction(clientWithAccount, {
|
|
157
|
+
hash: receipts[1].transactionHash,
|
|
158
|
+
}),
|
|
159
|
+
getTransaction(clientWithAccount, {
|
|
160
|
+
hash: receipts[2].transactionHash,
|
|
161
|
+
}),
|
|
162
|
+
])
|
|
163
|
+
expect(transactions[0].nonceKey).toBe(0n)
|
|
164
|
+
expect(transactions[1].nonceKey).toBeGreaterThan(0n)
|
|
165
|
+
expect(transactions[2].nonceKey).toBeGreaterThan(0n)
|
|
166
|
+
})
|
|
167
|
+
})
|
|
168
|
+
})
|
package/src/viem/Chain.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as Hex from 'ox/Hex'
|
|
1
2
|
import {
|
|
2
3
|
defineTransaction,
|
|
3
4
|
defineTransactionReceipt,
|
|
@@ -25,6 +26,25 @@ export type Chain<
|
|
|
25
26
|
})
|
|
26
27
|
|
|
27
28
|
function config<const chain extends Chain>(chain: chain) {
|
|
29
|
+
const nonceKeyManager = {
|
|
30
|
+
counter: 0,
|
|
31
|
+
resetScheduled: false,
|
|
32
|
+
reset() {
|
|
33
|
+
this.counter = 0
|
|
34
|
+
this.resetScheduled = false
|
|
35
|
+
},
|
|
36
|
+
get() {
|
|
37
|
+
if (!this.resetScheduled) {
|
|
38
|
+
this.resetScheduled = true
|
|
39
|
+
queueMicrotask(() => this.reset())
|
|
40
|
+
}
|
|
41
|
+
const count = this.counter
|
|
42
|
+
this.counter++
|
|
43
|
+
if (count === 0) return 0n
|
|
44
|
+
return Hex.toBigInt(Hex.random(6))
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
|
|
28
48
|
return {
|
|
29
49
|
blockTime: 1_000,
|
|
30
50
|
contracts: {
|
|
@@ -66,6 +86,22 @@ function config<const chain extends Chain>(chain: chain) {
|
|
|
66
86
|
),
|
|
67
87
|
}),
|
|
68
88
|
},
|
|
89
|
+
async prepareTransactionRequest(r) {
|
|
90
|
+
const request = r as Transaction.TransactionRequest
|
|
91
|
+
const nonceKey = (() => {
|
|
92
|
+
if (typeof request.nonceKey !== 'undefined') return request.nonceKey
|
|
93
|
+
return nonceKeyManager.get()
|
|
94
|
+
})()
|
|
95
|
+
|
|
96
|
+
const nonce = (() => {
|
|
97
|
+
if (typeof request.nonce === 'number') return request.nonce
|
|
98
|
+
// TODO: remove this line once `eth_fillTransaction` supports nonce keys.
|
|
99
|
+
if (nonceKey) return 0
|
|
100
|
+
return undefined
|
|
101
|
+
})()
|
|
102
|
+
|
|
103
|
+
return { ...request, nonce, nonceKey } as unknown as typeof r
|
|
104
|
+
},
|
|
69
105
|
serializers: {
|
|
70
106
|
// TODO: casting to satisfy viem – viem v3 to have more flexible serializer type.
|
|
71
107
|
transaction: ((transaction, signature) =>
|
|
@@ -88,7 +124,7 @@ function config<const chain extends Chain>(chain: chain) {
|
|
|
88
124
|
)) as SerializeTransactionFn,
|
|
89
125
|
},
|
|
90
126
|
...chain,
|
|
91
|
-
} as const
|
|
127
|
+
} as const satisfies viem_Chain
|
|
92
128
|
}
|
|
93
129
|
|
|
94
130
|
export function define<const chain extends viem_Chain>(
|