From bedb4f8641f6c92f3058c7214f4f07a74c1e025e Mon Sep 17 00:00:00 2001 From: jxom <7336481+jxom@users.noreply.github.com> Date: Mon, 22 Dec 2025 10:10:32 +1100 Subject: [PATCH 1/2] chore: rm viem --- .changeset/mighty-games-brake.md | 43 + AGENTS.md | 334 +- CHANGELOG.md | 8 +- README.md | 37 +- .../_template-example/src/wagmi.config.ts | 2 +- examples/accounts/src/wagmi.config.ts | 2 +- examples/exchange/src/App.tsx | 2 +- examples/exchange/src/wagmi.config.ts | 2 +- examples/issuance/src/wagmi.config.ts | 2 +- examples/payments/src/wagmi.config.ts | 4 +- examples/payments/worker/index.ts | 2 +- package.json | 14 +- playground/src/App.tsx | 5 +- playground/src/config.ts | 6 +- pnpm-lock.yaml | 215 +- pnpm-workspace.yaml | 2 +- src/chains.ts | 54 - src/server/Handler.test.ts | 4 +- src/server/Handler.ts | 33 +- src/viem/Abis.ts | 1688 ------- src/viem/Account.test.ts | 444 -- src/viem/Account.ts | 601 --- src/viem/Actions/account.test.ts | 414 -- src/viem/Actions/account.ts | 106 - src/viem/Actions/amm.test.ts | 381 -- src/viem/Actions/amm.ts | 1227 ----- src/viem/Actions/dex.test.ts | 1549 ------ src/viem/Actions/dex.ts | 2150 -------- src/viem/Actions/faucet.ts | 121 - src/viem/Actions/fee.test.ts | 259 - src/viem/Actions/fee.ts | 372 -- src/viem/Actions/index.ts | 9 - src/viem/Actions/nonce.test.ts | 206 - src/viem/Actions/nonce.ts | 347 -- src/viem/Actions/policy.test.ts | 534 -- src/viem/Actions/policy.ts | 1335 ----- src/viem/Actions/reward.test.ts | 434 -- src/viem/Actions/reward.ts | 944 ---- src/viem/Actions/token.test.ts | 3029 ----------- src/viem/Actions/token.ts | 4458 ----------------- src/viem/Addresses.ts | 9 - src/viem/Chain.bench-d.ts | 12 - src/viem/Chain.test.ts | 168 - src/viem/Chain.ts | 157 - src/viem/Decorator.bench-d.ts | 11 - src/viem/Decorator.test.ts | 39 - src/viem/Decorator.ts | 3179 ------------ src/viem/Formatters.ts | 164 - src/viem/P256.ts | 1 - src/viem/Secp256k1.ts | 1 - src/viem/Storage.ts | 110 - src/viem/TokenIds.ts | 1 - src/viem/Transaction.ts | 382 -- src/viem/Transport.ts | 191 - src/viem/WebAuthnP256.ts | 146 - src/viem/WebCryptoP256.ts | 1 - src/viem/e2e.test.ts | 1602 ------ src/viem/index.ts | 30 - src/viem/internal/types.ts | 69 - src/viem/internal/utils.ts | 58 - src/wagmi/Actions/amm.ts | 126 +- src/wagmi/Actions/dex.test.ts | 2 +- src/wagmi/Actions/dex.ts | 306 +- src/wagmi/Actions/faucet.ts | 22 +- src/wagmi/Actions/fee.ts | 40 +- src/wagmi/Actions/nonce.test.ts | 65 +- src/wagmi/Actions/nonce.ts | 152 +- src/wagmi/Actions/policy.ts | 168 +- src/wagmi/Actions/reward.ts | 125 +- src/wagmi/Actions/token.ts | 570 +-- src/wagmi/Connector.ts | 120 +- src/wagmi/Hooks/dex.test.ts | 2 +- src/wagmi/Hooks/fee.test.ts | 6 - src/wagmi/Hooks/nonce.test.ts | 67 +- src/wagmi/Hooks/nonce.ts | 115 +- src/wagmi/Hooks/policy.ts | 2 - src/wagmi/KeyManager.ts | 23 +- src/wagmi/internal/types.ts | 16 - test/config.ts | 8 +- test/server/config.ts | 119 + test/server/setup.ts | 8 +- test/viem-attest/setup.global.ts | 8 - test/viem/config.ts | 43 +- test/viem/setup.global.ts | 7 - test/viem/setup.ts | 19 - test/wagmi/config.ts | 5 +- test/wagmi/setup.ts | 2 +- vitest.config.ts | 40 - 88 files changed, 1133 insertions(+), 28763 deletions(-) create mode 100644 .changeset/mighty-games-brake.md delete mode 100644 src/chains.ts delete mode 100644 src/viem/Abis.ts delete mode 100644 src/viem/Account.test.ts delete mode 100644 src/viem/Account.ts delete mode 100644 src/viem/Actions/account.test.ts delete mode 100644 src/viem/Actions/account.ts delete mode 100644 src/viem/Actions/amm.test.ts delete mode 100644 src/viem/Actions/amm.ts delete mode 100644 src/viem/Actions/dex.test.ts delete mode 100644 src/viem/Actions/dex.ts delete mode 100644 src/viem/Actions/faucet.ts delete mode 100644 src/viem/Actions/fee.test.ts delete mode 100644 src/viem/Actions/fee.ts delete mode 100644 src/viem/Actions/index.ts delete mode 100644 src/viem/Actions/nonce.test.ts delete mode 100644 src/viem/Actions/nonce.ts delete mode 100644 src/viem/Actions/policy.test.ts delete mode 100644 src/viem/Actions/policy.ts delete mode 100644 src/viem/Actions/reward.test.ts delete mode 100644 src/viem/Actions/reward.ts delete mode 100644 src/viem/Actions/token.test.ts delete mode 100644 src/viem/Actions/token.ts delete mode 100644 src/viem/Addresses.ts delete mode 100644 src/viem/Chain.bench-d.ts delete mode 100644 src/viem/Chain.test.ts delete mode 100644 src/viem/Chain.ts delete mode 100644 src/viem/Decorator.bench-d.ts delete mode 100644 src/viem/Decorator.test.ts delete mode 100644 src/viem/Decorator.ts delete mode 100644 src/viem/Formatters.ts delete mode 100644 src/viem/P256.ts delete mode 100644 src/viem/Secp256k1.ts delete mode 100644 src/viem/Storage.ts delete mode 100644 src/viem/TokenIds.ts delete mode 100644 src/viem/Transaction.ts delete mode 100644 src/viem/Transport.ts delete mode 100644 src/viem/WebAuthnP256.ts delete mode 100644 src/viem/WebCryptoP256.ts delete mode 100644 src/viem/e2e.test.ts delete mode 100644 src/viem/index.ts delete mode 100644 src/viem/internal/types.ts delete mode 100644 src/viem/internal/utils.ts delete mode 100644 src/wagmi/internal/types.ts create mode 100644 test/server/config.ts delete mode 100644 test/viem-attest/setup.global.ts delete mode 100644 test/viem/setup.global.ts delete mode 100644 test/viem/setup.ts diff --git a/.changeset/mighty-games-brake.md b/.changeset/mighty-games-brake.md new file mode 100644 index 00000000..078e1690 --- /dev/null +++ b/.changeset/mighty-games-brake.md @@ -0,0 +1,43 @@ +--- +"tempo.ts": minor +--- + +**Breaking:** As of `viem@2.43.0`, `tempo.ts/chains` and `tempo.ts/viem` have been upstreamed into Viem, and are no longer maintained in this repository. + +```bash +pnpm i viem@2.43.0 +``` + +### Modify `chain` configuration + +The `tempo` chain has been renamed to `tempoTestnet`, and now becomes a standard chain object that can be `.extend`ed with a fee token, instead of a function. + +```diff +const client = createClient({ +- chain: tempo({ +- feeToken: '0x20c0000000000000000000000000000000000001' +- }), ++ chain: tempoTestnet.extend({ ++ feeToken: '0x20c0000000000000000000000000000000000001' ++ }), + transport: http(), +}) +``` + +### `Account#assignKeyAuthorization` has been removed + +The `Account#assignKeyAuthorization` function has been removed. Instead, you will need to assign the key authorization on a transaction manually on the next transaction. + +```diff +const accessKey = Account.fromP256(generatePrivateKey(), { + access: account, +}) + +const keyAuthorization = await account.signKeyAuthorization(accessKey) +- await account.assignKeyAuthorization(keyAuthorization) + +const receipt = await client.sendTransactionSync({ + account: accessKey, ++ keyAuthorization, +}) +``` \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 51a17697..c9c2af00 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,334 +4,6 @@ This document provides guidelines for AI code generation agents working on this ## Code Generation -### Viem - -When generating Viem actions (in `src/viem/Actions/`), follow these guidelines. - -An example of a generated action set can be found in `src/viem/Actions/token.ts`. - -#### Source of Truth - -- **All actions must be based on precompile contract specifications** in `test/docs/specs/`. -- It could be likely that some interfaces may be inconsistent between the specs (`test/docs/specs`) and the precompiles (`test/tempo/crates/contracts/src/precompiles`). Always prefer the precompile interfaces over the specs. -- If the specification is unclear or missing details, **prompt the developer** for guidance rather than making assumptions - -#### Documentation Requirements - -All actions **must include comprehensive JSDoc** with: - -1. **Function description** - What the action does -2. **`@example` block** - Complete working example showing: - - Required imports (`createClient`, `http`, action imports) - - Client setup with chain and transport - - Action usage with realistic parameters - - Expected return value handling (if applicable) -3. **`@param` tags** - For each parameter (client, parameters) -4. **`@returns` tag** - Description of the return value - -Example: -```typescript -/** - * Gets the pool ID for a token pair. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const poolId = await Actions.amm.getPoolId(client, { - * userToken: '0x...', - * validatorToken: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The pool ID. - */ -``` - -#### Action Types - -##### Read-Only Actions - -For view/pure functions that only read state: - -- Use `readContract` from `viem/actions` -- Return type should use `ReadContractReturnType` -- Parameters extend `ReadParameters` - -##### Mutate-Based Actions - -For state-changing functions, **both variants must be implemented**: - -**1. Standard Async Variant** - -- Uses `writeContract` from `viem/actions` -- Returns transaction hash -- Async operation that doesn't wait for confirmation - -```typescript -export async function myAction< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: myAction.Parameters, -): Promise { - return myAction.inner(writeContract, client, parameters) -} -``` - -**2. Sync Variant (`*Sync`)** - -- Named with `Sync` suffix (e.g., `mintSync`, `burnSync`, `rebalanceSwapSync`) -- Uses `writeContractSync` from `viem/actions` -- **Waits for transaction confirmation** -- Returns both the receipt and extracted event data -- **Must use `extractEvent` to get return values** (not `simulateContract`) - -```typescript -export async function myActionSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: myActionSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await myAction.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = myAction.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} -``` - -#### Namespace Properties - -All actions **must include** the following components within their namespace: - -##### 1. `Parameters` Type - -```typescript -// Read actions -export type Parameters = ReadParameters & Args - -// Write actions -export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, -> = WriteParameters & Args -``` - -##### 2. `Args` Type - -Arguments must be documented with JSDoc. - -```typescript -export type Args = { - /** JSDoc for each argument */ - argName: Type -} -``` - -##### 3. `ReturnValue` Type - -```typescript -// Read actions -export type ReturnValue = ReadContractReturnType - -// Write actions -export type ReturnValue = WriteContractReturnType -``` - -##### 4. `ErrorType` Type (for write actions) - -Write actions must include an `ErrorType` export. Use `BaseErrorType` from `viem` as a placeholder with a TODO comment for future exhaustive error typing: - -```typescript -// TODO: exhaustive error type -export type ErrorType = BaseErrorType -``` - -##### 5. `call` Function - -**Required for all actions** - enables composition with other viem actions: - -```typescript -/** - * Defines a call to the `functionName` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const hash = await client.sendTransaction({ - * calls: [actions.amm.myAction.call({ arg1, arg2 })], - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ -export function call(args: Args) { - return defineCall({ - address: Addresses.contractName, - abi: Abis.contractName, - args: [/* transformed args */], - functionName: 'functionName', - }) -} -``` - -The `call` function enables these use cases: -- `sendCalls` - Batch multiple calls in one transaction -- `sendTransaction` with `calls` - Send transaction with multiple operations -- `multicall` - Execute multiple calls in parallel -- `estimateContractGas` - Estimate gas costs -- `simulateContract` - Simulate execution - -##### 6. `extractEvent` Function (for mutate-based actions) - -**Required for all actions that emit events**: - -```typescript -/** - * Extracts the `EventName` event from logs. - * - * @param logs - The logs. - * @returns The `EventName` event. - */ -export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.contractName, - logs, - eventName: 'EventName', - strict: true, - }) - if (!log) throw new Error('`EventName` event not found.') - return log -} -``` - -##### 7. `inner` Function (for write actions) - -```typescript -/** @internal */ -export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, ->( - action: action, - client: Client, - parameters: Parameters, -): Promise> { - const { arg1, arg2, ...rest } = parameters - const call = myAction.call({ arg1, arg2 }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never -} -``` - -#### Namespace Structure - -Organize actions using namespace pattern: - -```typescript -export async function myAction(...) { ... } - -export namespace myAction { - export type Parameters = ... - export type Args = ... - export type ReturnValue = ... - - export async function inner(...) { ... } // for write actions - export function call(args: Args) { ... } - export function extractEvent(logs: Log[]) { ... } // for mutate actions -} -``` - -#### Decision-Making - -When encountering situations that require judgment: - -- **Specification ambiguities**: Prompt developer for clarification -- **Missing contract details**: Request ABI or specification update -- **Event structure uncertainty**: Ask for event definition -- **Parameter transformations**: Confirm expected input/output formats -- **Edge cases**: Discuss handling strategy with developer - -#### Naming Conventions - -- Action names should match contract function names (in camelCase) -- Sync variants use `Sync` suffix (e.g., `myActionSync`) -- Event names in `extractEvent` should match contract event names exactly -- Namespace components should be exported within the action's namespace - -#### Testing - -Tests should be co-located with actions in `*action-name*.test.ts` files. Reference contract tests in `test/tempo/crates/precompiles/` for expected behavior. - -See `src/viem/Actions/token.test.ts` for a comprehensive example of test patterns and structure. - -##### Test Structure - -Organize tests by action name with a default test case and behavior-specific tests: - -```typescript -describe('actionName', () => { - test('default', async () => { - // Test the primary/happy path scenario - const { receipt, ...result } = await Actions.namespace.actionSync(client, { - param1: value1, - param2: value2, - }) - - expect(receipt).toBeDefined() - expect(result).toMatchInlineSnapshot(`...`) - }) - - test('behavior: specific edge case', async () => { - // Test specific behaviors, edge cases, or variations - }) - - test('behavior: error conditions', async () => { - // Test error handling - await expect( - actions.namespace.actionSync(client, { ... }) - ).rejects.toThrow() - }) -}) - -describe.todo('unimplementedAction') -``` - ### Wagmi Actions When generating Wagmi actions (in `src/wagmi/Actions/`), follow these guidelines. @@ -365,13 +37,13 @@ Example: * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempoTestnet } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { - * [tempo.id]: http(), + * [tempoTestnet.id]: http(), * }, * }) * diff --git a/CHANGELOG.md b/CHANGELOG.md index d23e8459..50da1e45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -531,11 +531,11 @@ ```diff -import { createTempoClient } from 'tempo.ts/viem' +import { createClient, http } from 'viem' - +import { tempo } from 'tempo.ts/chains' + +import { tempo } from 'viem/chains' -const client = createTempoClient() +const client = createClient({ - + chain: tempo({ + + chain: tempoTestnet.extend({ + feeToken: '0x20c0000000000000000000000000000000000001' + }), + transport: http(), @@ -560,7 +560,7 @@ ```ts // fee token NOT set on client const client2 = createClient({ - chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) + chain: tempoTestnet transport: http(), }); @@ -577,7 +577,7 @@ ```ts const client1 = createClient({ - chain: tempo({ feeToken: "0x20c...001" }), // note: pass `null` to opt-in to protocol preferences. + chain: tempoTestnet.extend({ feeToken: "0x20c...001" }), // note: pass `null` to opt-in to protocol preferences. transport: http(), }); diff --git a/README.md b/README.md index 97246121..54d3e491 100644 --- a/README.md +++ b/README.md @@ -25,61 +25,30 @@ pnpm i tempo.ts ``` -If you wish to use `tempo.ts/prool` for programmatic Tempo node instances, you will need -to ensure you have access to [`tempoxyz/tempo`](https://github.com/tempoxyz/tempo) and are logged into the GitHub Container Registry: - -```sh -docker login ghcr.io -``` - ## Entrypoints | Entrypoint | Description | | ---------------- | ---------------------------------------- | -| `tempo.ts/viem` | Tempo extension for Viem. | | `tempo.ts/wagmi` | Tempo actions/hooks for Wagmi. | ## Usage -### `tempo.ts/viem` - -```ts -import { createClient, http, publicActions, walletActions } from 'viem'; -import { tempo } from 'tempo.ts/chains'; - -const client = createClient({ - chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), - transport: http(), -}) - .extend(publicActions) - .extend(walletActions); - -const hash = await client.sendTransaction({ - calls: [ - { data: '0x...', to: '0x...' }, - { data: '0x...', to: '0x...' }, - ], -}); - -const transaction = await client.getTransaction({ hash }); -``` - ### `tempo.ts/wagmi` ```ts import { createConfig, http } from 'wagmi'; -import { tempo } from 'tempo.ts/chains'; +import { tempoTestnet } from 'viem/chains'; import { Actions, Hooks, KeyManager, webauthn } from 'tempo.ts/wagmi'; export const config = createConfig({ - chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + chains: [tempoTestnet.extend({ feeToken: '0x20c0000000000000000000000000000000000001' })], connectors: [ webAuthn({ keyManager: KeyManager.localStorage(), }) ], transports: { - [tempo.id]: http(), + [tempoTestnet.id]: http(), }, }); diff --git a/examples/_template-example/src/wagmi.config.ts b/examples/_template-example/src/wagmi.config.ts index b42b8f11..1e1b34bf 100644 --- a/examples/_template-example/src/wagmi.config.ts +++ b/examples/_template-example/src/wagmi.config.ts @@ -1,6 +1,6 @@ import { QueryClient } from '@tanstack/react-query' -import { tempoTestnet } from 'tempo.ts/chains' import { KeyManager, webAuthn } from 'tempo.ts/wagmi' +import { tempoTestnet } from 'viem/chains' import { createConfig, webSocket } from 'wagmi' export const alphaUsd = '0x20c0000000000000000000000000000000000001' diff --git a/examples/accounts/src/wagmi.config.ts b/examples/accounts/src/wagmi.config.ts index edaf9600..d66c6c7e 100644 --- a/examples/accounts/src/wagmi.config.ts +++ b/examples/accounts/src/wagmi.config.ts @@ -1,6 +1,6 @@ import { QueryClient } from '@tanstack/react-query' -import { tempoTestnet } from 'tempo.ts/chains' import { KeyManager, webAuthn } from 'tempo.ts/wagmi' +import { tempoTestnet } from 'viem/chains' import { createConfig, webSocket } from 'wagmi' export const alphaUsd = '0x20c0000000000000000000000000000000000001' diff --git a/examples/exchange/src/App.tsx b/examples/exchange/src/App.tsx index fd36e91c..eb71eb7e 100644 --- a/examples/exchange/src/App.tsx +++ b/examples/exchange/src/App.tsx @@ -1,6 +1,6 @@ -import { Actions, Addresses } from 'tempo.ts/viem' import { Hooks } from 'tempo.ts/wagmi' import { formatUnits, parseUnits } from 'viem' +import { Actions, Addresses } from 'viem/tempo' import { useAccount, useConnect, diff --git a/examples/exchange/src/wagmi.config.ts b/examples/exchange/src/wagmi.config.ts index dc90cc92..51fdca01 100644 --- a/examples/exchange/src/wagmi.config.ts +++ b/examples/exchange/src/wagmi.config.ts @@ -1,6 +1,6 @@ import { QueryClient } from '@tanstack/react-query' -import { tempoTestnet } from 'tempo.ts/chains' import { KeyManager, webAuthn } from 'tempo.ts/wagmi' +import { tempoTestnet } from 'viem/chains' import { createConfig, webSocket } from 'wagmi' export const pathUsd = '0x20c0000000000000000000000000000000000000' diff --git a/examples/issuance/src/wagmi.config.ts b/examples/issuance/src/wagmi.config.ts index 26e4190b..48712b75 100644 --- a/examples/issuance/src/wagmi.config.ts +++ b/examples/issuance/src/wagmi.config.ts @@ -1,6 +1,6 @@ import { QueryClient } from '@tanstack/react-query' -import { tempoTestnet } from 'tempo.ts/chains' import { KeyManager, webAuthn } from 'tempo.ts/wagmi' +import { tempoTestnet } from 'viem/chains' import { createConfig, webSocket } from 'wagmi' export const pathUsd = '0x20c0000000000000000000000000000000000000' diff --git a/examples/payments/src/wagmi.config.ts b/examples/payments/src/wagmi.config.ts index 41446373..5ca34b90 100644 --- a/examples/payments/src/wagmi.config.ts +++ b/examples/payments/src/wagmi.config.ts @@ -1,8 +1,8 @@ import { QueryClient } from '@tanstack/react-query' -import { tempoTestnet } from 'tempo.ts/chains' -import { withFeePayer } from 'tempo.ts/viem' import { KeyManager, webAuthn } from 'tempo.ts/wagmi' import { mnemonicToAccount } from 'viem/accounts' +import { tempoTestnet } from 'viem/chains' +import { withFeePayer } from 'viem/tempo' import { createConfig, http, webSocket } from 'wagmi' export const alphaUsd = '0x20c0000000000000000000000000000000000001' diff --git a/examples/payments/worker/index.ts b/examples/payments/worker/index.ts index e0e44fcd..b54a33d7 100644 --- a/examples/payments/worker/index.ts +++ b/examples/payments/worker/index.ts @@ -1,6 +1,6 @@ -import { tempoTestnet } from 'tempo.ts/chains' import { Handler } from 'tempo.ts/server' import { http } from 'viem' +import { tempoTestnet } from 'viem/chains' import { alphaUsd, sponsorAccount } from '../src/wagmi.config' export default { diff --git a/package.json b/package.json index 281f3560..7e655cbb 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ }, "pnpm": { "overrides": { - "ox": "~0.10.2", + "ox": "~0.11.1", "tempo.ts": "workspace:*", "viem": "catalog:default" } @@ -74,7 +74,7 @@ "dependencies": { "@remix-run/fetch-router": "~0.12.0", "idb-keyval": "^6.2.2", - "ox": "~0.10.2" + "ox": "~0.11.1" }, "peerDependencies": { "@tanstack/query-core": ">=5.0.0", @@ -123,21 +123,11 @@ "types": "./dist/index.d.ts", "default": "./dist/index.js" }, - "./chains": { - "src": "./src/chains.ts", - "types": "./dist/chains.d.ts", - "default": "./dist/chains.js" - }, "./server": { "src": "./src/server/index.ts", "types": "./dist/server/index.d.ts", "default": "./dist/server/index.js" }, - "./viem": { - "src": "./src/viem/index.ts", - "types": "./dist/viem/index.d.ts", - "default": "./dist/viem/index.js" - }, "./wagmi": { "src": "./src/wagmi/index.ts", "types": "./dist/wagmi/index.d.ts", diff --git a/playground/src/App.tsx b/playground/src/App.tsx index 7b2fb30c..e77b476f 100644 --- a/playground/src/App.tsx +++ b/playground/src/App.tsx @@ -1,7 +1,6 @@ import { useMutation } from '@tanstack/react-query' import { Address } from 'ox' import { useState } from 'react' -import { Actions } from 'tempo.ts/viem' import { Hooks } from 'tempo.ts/wagmi' import { type Chain, @@ -12,6 +11,7 @@ import { type Transport, } from 'viem' import { mnemonicToAccount } from 'viem/accounts' +import { Actions } from 'viem/tempo' import { useAccount, useChains, @@ -94,6 +94,8 @@ function Connect() { const connect = useConnect() const connectors = useConnectors() + console.log(connect.error) + return ( <> {connectors.map((connector) => ( @@ -188,7 +190,6 @@ function Balance() { params: [account.address], }) } else { - // @ts-expect-error - TODO: fix this await Actions.token.transferSync(client as Client, { account: mnemonicToAccount( 'test test test test test test test test test test test junk', diff --git a/playground/src/config.ts b/playground/src/config.ts index 0b223716..c40e165b 100644 --- a/playground/src/config.ts +++ b/playground/src/config.ts @@ -1,10 +1,10 @@ import { QueryClient } from '@tanstack/react-query' -import { tempoDevnet, tempoLocal, tempoTestnet } from 'tempo.ts/chains' import { dangerous_secp256k1, KeyManager, webAuthn } from 'tempo.ts/wagmi' +import { tempoDevnet, tempoLocalnet, tempoTestnet } from 'viem/chains' import { createConfig, http } from 'wagmi' const chain = (() => { - if (import.meta.env.VITE_NODE_ENV === 'localnet') return tempoLocal + if (import.meta.env.VITE_NODE_ENV === 'localnet') return tempoLocalnet if (import.meta.env.VITE_NODE_ENV === 'devnet') return tempoDevnet return tempoTestnet })() @@ -13,7 +13,7 @@ export const config = createConfig({ batch: { multicall: false, }, - chains: [chain({ feeToken: 1n })], + chains: [chain.extend({ feeToken: 1n })], connectors: [ webAuthn({ grantAccessKey: true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 049bcf10..dd941424 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,9 +38,9 @@ catalogs: version: 3.0.1 overrides: - ox: ~0.10.2 + ox: ~0.11.1 tempo.ts: workspace:* - viem: ^2.41.2 + viem: https://pkg.pr.new/viem@28ba089 importers: @@ -53,8 +53,11 @@ importers: specifier: ^6.2.2 version: 6.2.2 ox: - specifier: ~0.10.2 - version: 0.10.2(typescript@5.9.3)(zod@4.1.13) + specifier: ~0.11.1 + version: 0.11.1(typescript@5.9.3)(zod@4.1.13) + viem: + specifier: https://pkg.pr.new/viem@28ba089 + version: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) devDependencies: '@ark/attest': specifier: ^0.51.0 @@ -109,7 +112,7 @@ importers: version: 4.0.13(@vitest/browser@4.0.13(bufferutil@4.0.9)(utf-8-validate@5.0.10)(vite@7.2.2(@types/node@24.10.1)(lightningcss@1.30.2)(yaml@2.8.2))(vitest@4.0.13))(vitest@4.0.13) '@wagmi/core': specifier: catalog:default - version: 3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)) + version: 3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)) elysia: specifier: ^1.4.16 version: 1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3) @@ -143,9 +146,6 @@ importers: typescript: specifier: catalog:default version: 5.9.3 - viem: - specifier: ^2.41.2 - version: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) vitest: specifier: ^4.0.13 version: 4.0.13(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-playwright@4.0.13)(lightningcss@1.30.2)(yaml@2.8.2) @@ -154,7 +154,7 @@ importers: version: 2.0.2(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vitest@4.0.13) wagmi: specifier: catalog:default - version: 3.0.1(4a536769f178bc33ed063a7dc8423bf5) + version: 3.0.1(df8fbaebfe64a9042acc725a7a0b6dc9) zile: specifier: ^0.0.13 version: 0.0.13(@typescript/native-preview@7.0.0-dev.20251110.1)(typescript@5.9.3) @@ -174,11 +174,11 @@ importers: specifier: workspace:* version: link:../.. viem: - specifier: ^2.41.2 - version: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + specifier: https://pkg.pr.new/viem@28ba089 + version: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) wagmi: specifier: ^3 - version: 3.0.1(4a536769f178bc33ed063a7dc8423bf5) + version: 3.0.1(df8fbaebfe64a9042acc725a7a0b6dc9) devDependencies: '@cloudflare/vite-plugin': specifier: ^1.13.18 @@ -220,8 +220,8 @@ importers: specifier: ^5 version: 5.90.5(react@19.2.0) ox: - specifier: ~0.10.2 - version: 0.10.2(typescript@5.9.3)(zod@4.1.13) + specifier: ~0.11.1 + version: 0.11.1(typescript@5.9.3)(zod@4.1.13) react: specifier: ^19 version: 19.2.0 @@ -232,11 +232,11 @@ importers: specifier: workspace:* version: link:../.. viem: - specifier: ^2.41.2 - version: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + specifier: https://pkg.pr.new/viem@28ba089 + version: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) wagmi: specifier: ^3 - version: 3.0.1(4a536769f178bc33ed063a7dc8423bf5) + version: 3.0.1(df8fbaebfe64a9042acc725a7a0b6dc9) devDependencies: '@cloudflare/vite-plugin': specifier: ^1.13.18 @@ -284,11 +284,11 @@ importers: specifier: workspace:* version: link:../.. viem: - specifier: ^2.41.2 - version: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + specifier: https://pkg.pr.new/viem@28ba089 + version: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) wagmi: specifier: ^3 - version: 3.0.1(4a536769f178bc33ed063a7dc8423bf5) + version: 3.0.1(df8fbaebfe64a9042acc725a7a0b6dc9) devDependencies: '@types/node': specifier: ^24.10.0 @@ -327,11 +327,11 @@ importers: specifier: workspace:* version: link:../.. viem: - specifier: ^2.41.2 - version: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + specifier: https://pkg.pr.new/viem@28ba089 + version: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) wagmi: specifier: ^3 - version: 3.0.1(4a536769f178bc33ed063a7dc8423bf5) + version: 3.0.1(df8fbaebfe64a9042acc725a7a0b6dc9) devDependencies: '@types/node': specifier: ^24.10.0 @@ -370,11 +370,11 @@ importers: specifier: workspace:* version: link:../.. viem: - specifier: ^2.41.2 - version: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + specifier: https://pkg.pr.new/viem@28ba089 + version: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) wagmi: specifier: ^3 - version: 3.0.1(4a536769f178bc33ed063a7dc8423bf5) + version: 3.0.1(df8fbaebfe64a9042acc725a7a0b6dc9) devDependencies: '@cloudflare/vite-plugin': specifier: ^1.13.18 @@ -428,11 +428,11 @@ importers: specifier: workspace:* version: link:.. viem: - specifier: ^2.41.2 - version: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + specifier: https://pkg.pr.new/viem@28ba089 + version: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) wagmi: specifier: catalog:default - version: 3.0.1(4a536769f178bc33ed063a7dc8423bf5) + version: 3.0.1(df8fbaebfe64a9042acc725a7a0b6dc9) devDependencies: '@types/node': specifier: ^24.6.0 @@ -1110,8 +1110,9 @@ packages: '@gemini-wallet/core@0.3.2': resolution: {integrity: sha512-Z4aHi3ECFf5oWYWM3F1rW83GJfB9OvhBYPTmb5q+VyK3uvzvS48lwo+jwh2eOoCRWEuT/crpb9Vwp2QaS5JqgQ==} + version: 0.3.2 peerDependencies: - viem: ^2.41.2 + viem: '>=2.0.0' '@grpc/grpc-js@1.14.2': resolution: {integrity: sha512-QzVUtEFyu05UNx2xr0fCQmStUO17uVQhGNowtxs00IgTZT6/W2PBLfUkj30s0FKJ29VtTa3ArVNIhNP6akQhqA==} @@ -2199,7 +2200,7 @@ packages: '@walletconnect/ethereum-provider': ~2.21.1 porto: ~0.2.35 typescript: '>=5.7.3' - viem: ^2.41.2 + viem: 2.x peerDependenciesMeta: '@base-org/account': optional: true @@ -2222,10 +2223,11 @@ packages: '@wagmi/core@3.0.0': resolution: {integrity: sha512-wOn8jwB9GNYTdrc4CP/huf1aAhDoQ5GKl5OhxGBZx9X4qE+wReW05dTcurEc+XBl9B/ZVis2JdXVU3ZiYqyS8Q==} + version: 3.0.0 peerDependencies: '@tanstack/query-core': '>=5.0.0' typescript: '>=5.7.3' - viem: ^2.41.2 + viem: 2.x peerDependenciesMeta: '@tanstack/query-core': optional: true @@ -2245,6 +2247,7 @@ packages: '@walletconnect/ethereum-provider@2.21.1': resolution: {integrity: sha512-SSlIG6QEVxClgl1s0LMk4xr2wg4eT3Zn/Hb81IocyqNSGfXpjtawWxKxiC5/9Z95f1INyBD6MctJbL/R1oBwIw==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' '@walletconnect/events@1.0.1': resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} @@ -2289,9 +2292,11 @@ packages: '@walletconnect/sign-client@2.21.0': resolution: {integrity: sha512-z7h+PeLa5Au2R591d/8ZlziE0stJvdzP9jNFzFolf2RG/OiXulgFKum8PrIyXy+Rg2q95U9nRVUF9fWcn78yBA==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' '@walletconnect/sign-client@2.21.1': resolution: {integrity: sha512-QaXzmPsMnKGV6tc4UcdnQVNOz4zyXgarvdIQibJ4L3EmLat73r5ZVl4c0cCOcoaV7rgM9Wbphgu5E/7jNcd3Zg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' '@walletconnect/time@1.0.2': resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} @@ -2304,9 +2309,11 @@ packages: '@walletconnect/universal-provider@2.21.0': resolution: {integrity: sha512-mtUQvewt+X0VBQay/xOJBvxsB3Xsm1lTwFjZ6WUwSOTR1X+FNb71hSApnV5kbsdDIpYPXeQUbGt2se1n5E5UBg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' '@walletconnect/universal-provider@2.21.1': resolution: {integrity: sha512-Wjx9G8gUHVMnYfxtasC9poGm8QMiPCpXpbbLFT+iPoQskDDly8BwueWnqKs4Mx2SdIAWAwuXeZ5ojk5qQOxJJg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' '@walletconnect/utils@2.21.0': resolution: {integrity: sha512-zfHLiUoBrQ8rP57HTPXW7rQMnYxYI4gT9yTACxVW6LhIFROTF6/ytm5SKNoIvi4a5nX5dfXG4D9XwQUCu8Ilig==} @@ -2331,19 +2338,8 @@ packages: zod: optional: true - abitype@1.1.0: - resolution: {integrity: sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==} - peerDependencies: - typescript: '>=5.0.4' - zod: ^3.22.0 || ^4.0.0 - peerDependenciesMeta: - typescript: - optional: true - zod: - optional: true - - abitype@1.1.1: - resolution: {integrity: sha512-Loe5/6tAgsBukY95eGaPSDmQHIjRZYQq8PB1MpsNccDIK8WiV+Uw6WzaIXipvaxTEL2yEB0OpEaQv3gs8pkS9Q==} + abitype@1.2.3: + resolution: {integrity: sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==} peerDependencies: typescript: '>=5.0.4' zod: ^3.22.0 || ^4.0.0 @@ -3848,8 +3844,8 @@ packages: outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - ox@0.10.2: - resolution: {integrity: sha512-fsUKAW7Jr64vEwppzKeOHR7mElxTIPgmcf1vgw0mhpWsCbYnPe7G8bM3c5R55lwhV2k67gFANeoSXrk8cAEPuQ==} + ox@0.11.1: + resolution: {integrity: sha512-1l1gOLAqg0S0xiN1dH5nkPna8PucrZgrIJOfS49MLNiMevxu07Iz4ZjuJS9N+xifvT+PsZyIptS7WHM8nC+0+A==} peerDependencies: typescript: '>=5.4.0' peerDependenciesMeta: @@ -3976,6 +3972,7 @@ packages: porto@0.2.35: resolution: {integrity: sha512-gu9FfjjvvYBgQXUHWTp6n3wkTxVtEcqFotM7i3GEZeoQbvLGbssAicCz6hFZ8+xggrJWwi/RLmbwNra50SMmUQ==} + version: 0.2.35 hasBin: true peerDependencies: '@tanstack/react-query': '>=5.59.0' @@ -3986,7 +3983,7 @@ packages: react: '>=18' react-native: '>=0.81.4' typescript: '>=5.4.0' - viem: ^2.41.2 + viem: '>=2.37.0' wagmi: '>=2.0.0' peerDependenciesMeta: '@tanstack/react-query': @@ -4670,8 +4667,9 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - viem@2.41.2: - resolution: {integrity: sha512-LYliajglBe1FU6+EH9mSWozp+gRA/QcHfxeD9Odf83AdH5fwUS7DroH4gHvlv6Sshqi1uXrYFA2B/EOczxd15g==} + viem@https://pkg.pr.new/viem@28ba089: + resolution: {tarball: https://pkg.pr.new/viem@28ba089} + version: 2.43.3-28ba089.0 peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -4815,7 +4813,7 @@ packages: '@tanstack/react-query': '>=5.0.0' react: '>=18' typescript: '>=5.7.3' - viem: ^2.41.2 + viem: 2.x peerDependenciesMeta: typescript: optional: true @@ -5214,9 +5212,9 @@ snapshots: clsx: 1.2.1 eventemitter3: 5.0.1 idb-keyval: 6.2.1 - ox: 0.10.2(typescript@5.9.3)(zod@4.1.13) + ox: 0.11.1(typescript@5.9.3)(zod@4.1.13) preact: 10.24.2 - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) zustand: 5.0.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) transitivePeerDependencies: - '@types/react' @@ -5515,7 +5513,7 @@ snapshots: jose: 6.1.2 md5: 2.3.0 uncrypto: 0.1.3 - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -5533,9 +5531,9 @@ snapshots: clsx: 1.2.1 eventemitter3: 5.0.1 idb-keyval: 6.2.1 - ox: 0.10.2(typescript@5.9.3)(zod@4.1.13) + ox: 0.11.1(typescript@5.9.3)(zod@4.1.13) preact: 10.24.2 - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) zustand: 5.0.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) transitivePeerDependencies: - '@types/react' @@ -5739,11 +5737,11 @@ snapshots: micro-ftch: 0.3.1 optional: true - '@gemini-wallet/core@0.3.2(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13))': + '@gemini-wallet/core@0.3.2(viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13))': dependencies: '@metamask/rpc-errors': 7.0.2 eventemitter3: 5.0.1 - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) transitivePeerDependencies: - supports-color optional: true @@ -6218,7 +6216,7 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) transitivePeerDependencies: - bufferutil - typescript @@ -6230,7 +6228,7 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) transitivePeerDependencies: - bufferutil - typescript @@ -6244,7 +6242,7 @@ snapshots: '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6399,7 +6397,7 @@ snapshots: '@walletconnect/logger': 2.1.2 '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6455,7 +6453,7 @@ snapshots: '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) bs58: 6.0.0 valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6567,7 +6565,7 @@ snapshots: '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) transitivePeerDependencies: - bufferutil - typescript @@ -7431,26 +7429,26 @@ snapshots: '@vitest/pretty-format': 4.0.13 tinyrainbow: 3.0.3 - '@wagmi/connectors@7.0.1(5ace2927f32383ba5d60129f3ab2cb18)': + '@wagmi/connectors@7.0.1(238ccb15a0c16d9e4c2e338bba3e7fbd)': dependencies: - '@wagmi/core': 3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)) - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + '@wagmi/core': 3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) optionalDependencies: '@base-org/account': 2.4.0(@types/react@19.2.2)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.1.13) '@coinbase/wallet-sdk': 4.3.6(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@4.1.13) - '@gemini-wallet/core': 0.3.2(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)) + '@gemini-wallet/core': 0.3.2(viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)) '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) - porto: 0.2.35(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)))(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13))(wagmi@3.0.1) + porto: 0.2.35(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)))(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13))(wagmi@3.0.1) typescript: 5.9.3 - '@wagmi/core@3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13))': + '@wagmi/core@3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.9.3) - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) zustand: 5.0.0(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) optionalDependencies: '@tanstack/query-core': 5.90.5 @@ -7942,7 +7940,7 @@ snapshots: detect-browser: 5.3.0 query-string: 7.1.3 uint8arrays: 3.1.0 - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7987,7 +7985,7 @@ snapshots: detect-browser: 5.3.0 query-string: 7.1.3 uint8arrays: 3.1.0 - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8031,36 +8029,19 @@ snapshots: zod: 3.25.76 optional: true - abitype@1.1.0(typescript@5.9.3)(zod@3.22.4): - optionalDependencies: - typescript: 5.9.3 - zod: 3.22.4 - optional: true - - abitype@1.1.0(typescript@5.9.3)(zod@3.25.76): - optionalDependencies: - typescript: 5.9.3 - zod: 3.25.76 - optional: true - - abitype@1.1.0(typescript@5.9.3)(zod@4.1.13): - optionalDependencies: - typescript: 5.9.3 - zod: 4.1.13 - - abitype@1.1.1(typescript@5.9.3)(zod@3.22.4): + abitype@1.2.3(typescript@5.9.3)(zod@3.22.4): optionalDependencies: typescript: 5.9.3 zod: 3.22.4 optional: true - abitype@1.1.1(typescript@5.9.3)(zod@3.25.76): + abitype@1.2.3(typescript@5.9.3)(zod@3.25.76): optionalDependencies: typescript: 5.9.3 zod: 3.25.76 optional: true - abitype@1.1.1(typescript@5.9.3)(zod@4.1.13): + abitype@1.2.3(typescript@5.9.3)(zod@4.1.13): optionalDependencies: typescript: 5.9.3 zod: 4.1.13 @@ -9562,7 +9543,7 @@ snapshots: outdent@0.5.0: {} - ox@0.10.2(typescript@5.9.3)(zod@3.22.4): + ox@0.11.1(typescript@5.9.3)(zod@3.22.4): dependencies: '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 @@ -9570,7 +9551,7 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.1(typescript@5.9.3)(zod@3.22.4) + abitype: 1.2.3(typescript@5.9.3)(zod@3.22.4) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.3 @@ -9578,7 +9559,7 @@ snapshots: - zod optional: true - ox@0.10.2(typescript@5.9.3)(zod@3.25.76): + ox@0.11.1(typescript@5.9.3)(zod@3.25.76): dependencies: '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 @@ -9586,7 +9567,7 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.1(typescript@5.9.3)(zod@3.25.76) + abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.3 @@ -9594,7 +9575,7 @@ snapshots: - zod optional: true - ox@0.10.2(typescript@5.9.3)(zod@4.1.13): + ox@0.11.1(typescript@5.9.3)(zod@4.1.13): dependencies: '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 @@ -9602,7 +9583,7 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.1(typescript@5.9.3)(zod@4.1.13) + abitype: 1.2.3(typescript@5.9.3)(zod@4.1.13) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.3 @@ -9710,21 +9691,21 @@ snapshots: pony-cause@2.1.11: optional: true - porto@0.2.35(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)))(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13))(wagmi@3.0.1): + porto@0.2.35(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)))(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13))(wagmi@3.0.1): dependencies: - '@wagmi/core': 3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)) + '@wagmi/core': 3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)) hono: 4.10.6 idb-keyval: 6.2.2 mipd: 0.0.7(typescript@5.9.3) - ox: 0.10.2(typescript@5.9.3)(zod@4.1.13) - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + ox: 0.11.1(typescript@5.9.3)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) zod: 4.1.13 zustand: 5.0.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) optionalDependencies: '@tanstack/react-query': 5.90.5(react@19.2.0) react: 19.2.0 typescript: 5.9.3 - wagmi: 3.0.1(4a536769f178bc33ed063a7dc8423bf5) + wagmi: 3.0.1(df8fbaebfe64a9042acc725a7a0b6dc9) transitivePeerDependencies: - '@types/react' - immer @@ -10484,15 +10465,15 @@ snapshots: vary@1.1.2: {} - viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4): + viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.3)(zod@3.22.4) + abitype: 1.2.3(typescript@5.9.3)(zod@3.22.4) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.10.2(typescript@5.9.3)(zod@3.22.4) + ox: 0.11.1(typescript@5.9.3)(zod@3.22.4) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.3 @@ -10502,15 +10483,15 @@ snapshots: - zod optional: true - viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): + viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.3)(zod@3.25.76) + abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.10.2(typescript@5.9.3)(zod@3.25.76) + ox: 0.11.1(typescript@5.9.3)(zod@3.25.76) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.3 @@ -10520,15 +10501,15 @@ snapshots: - zod optional: true - viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13): + viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.3)(zod@4.1.13) + abitype: 1.2.3(typescript@5.9.3)(zod@4.1.13) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.10.2(typescript@5.9.3)(zod@4.1.13) + ox: 0.11.1(typescript@5.9.3)(zod@4.1.13) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.3 @@ -10628,14 +10609,14 @@ snapshots: - tsx - yaml - wagmi@3.0.1(4a536769f178bc33ed063a7dc8423bf5): + wagmi@3.0.1(df8fbaebfe64a9042acc725a7a0b6dc9): dependencies: '@tanstack/react-query': 5.90.5(react@19.2.0) - '@wagmi/connectors': 7.0.1(5ace2927f32383ba5d60129f3ab2cb18) - '@wagmi/core': 3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)) + '@wagmi/connectors': 7.0.1(238ccb15a0c16d9e4c2e338bba3e7fbd) + '@wagmi/core': 3.0.0(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13)) react: 19.2.0 use-sync-external-store: 1.4.0(react@19.2.0) - viem: 2.41.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) + viem: https://pkg.pr.new/viem@28ba089(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.13) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 1752c6a1..fc065d2c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -13,7 +13,7 @@ catalog: react: ^19.1.1 react-dom: ^19.1.1 typescript: ^5.9.3 - viem: ^2.41.2 + viem: https://pkg.pr.new/viem@28ba089 wagmi: ^3.0.1 onlyBuiltDependencies: diff --git a/src/chains.ts b/src/chains.ts deleted file mode 100644 index 5beaeafd..00000000 --- a/src/chains.ts +++ /dev/null @@ -1,54 +0,0 @@ -import * as Chain from './viem/Chain.js' - -export const tempoDevnet = /*#__PURE__*/ Chain.define({ - id: 1337, - name: 'Tempo Devnet', - nativeCurrency: { - name: 'USD', - symbol: 'USD', - decimals: 6, - }, - rpcUrls: { - default: { - http: ['https://rpc.devnet.tempo.xyz'], - webSocket: ['wss://rpc.devnet.tempo.xyz'], - }, - }, -}) - -export const tempoLocal = /*#__PURE__*/ Chain.define({ - id: 1337, - name: 'Tempo', - nativeCurrency: { - name: 'USD', - symbol: 'USD', - decimals: 6, - }, - rpcUrls: { - default: { http: ['http://localhost:8545'] }, - }, -}) - -export const tempoTestnet = /*#__PURE__*/ Chain.define({ - id: 42429, - blockExplorers: { - default: { - name: 'Tempo Explorer', - url: 'https://explore.tempo.xyz', - }, - }, - name: 'Tempo Testnet', - nativeCurrency: { - name: 'USD', - symbol: 'USD', - decimals: 6, - }, - rpcUrls: { - default: { - http: ['https://rpc.testnet.tempo.xyz'], - webSocket: ['wss://rpc.testnet.tempo.xyz'], - }, - }, -}) - -export const tempo = /*#__PURE__*/ tempoTestnet diff --git a/src/server/Handler.test.ts b/src/server/Handler.test.ts index b2c1a13f..36948da2 100644 --- a/src/server/Handler.test.ts +++ b/src/server/Handler.test.ts @@ -5,6 +5,7 @@ import type { RpcRequest } from 'ox' import * as Base64 from 'ox/Base64' import * as Hex from 'ox/Hex' import { sendTransactionSync } from 'viem/actions' +import { withFeePayer } from 'viem/tempo' import { afterAll, afterEach, @@ -14,9 +15,8 @@ import { expect, test, } from 'vitest' +import { accounts, getClient, http } from '../../test/server/config.js' import { createServer, type Server } from '../../test/server/utils.js' -import { accounts, getClient, http } from '../../test/viem/config.js' -import { withFeePayer } from '../viem/Transport.js' import * as Handler from './Handler.js' import * as Kv from './Kv.js' diff --git a/src/server/Handler.ts b/src/server/Handler.ts index 7bec27d8..5d30a4c7 100644 --- a/src/server/Handler.ts +++ b/src/server/Handler.ts @@ -11,9 +11,8 @@ import type * as WebAuthnP256 from 'ox/WebAuthnP256' import { type Chain, type Client, createClient, type Transport } from 'viem' import type { LocalAccount } from 'viem/accounts' import { signTransaction } from 'viem/actions' +import { Formatters, Transaction } from 'viem/tempo' import type { OneOf } from '../internal/types.js' -import { formatTransaction } from '../viem/Formatters.js' -import * as Transaction from '../viem/Transaction.js' import * as RequestListener from './internal/requestListener.js' import type * as Kv from './Kv.js' @@ -349,11 +348,11 @@ export declare namespace keyManager { * ```ts * import { createClient, http } from 'viem' * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Handler } from 'tempo.ts/server' * * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), + * chain: tempoTestnet.extend({ feeToken: '0x20c0000000000000000000000000000000000001' }), * transport: http(), * }) * @@ -373,11 +372,11 @@ export declare namespace keyManager { * ```ts * import { createClient, http } from 'viem' * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Handler } from 'tempo.ts/server' * * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), + * chain: tempoTestnet.extend({ feeToken: '0x20c0000000000000000000000000000000000001' }), * transport: http(), * }) * @@ -396,11 +395,11 @@ export declare namespace keyManager { * ```ts * import { createClient, http } from 'viem' * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Handler } from 'tempo.ts/server' * * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), + * chain: tempoTestnet.extend({ feeToken: '0x20c0000000000000000000000000000000000001' }), * transport: http(), * }) * @@ -421,11 +420,11 @@ export declare namespace keyManager { * ```ts * import { createClient, http } from 'viem' * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Handler } from 'tempo.ts/server' * * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), + * chain: tempoTestnet.extend({ feeToken: '0x20c0000000000000000000000000000000000001' }), * transport: http(), * }) * @@ -444,12 +443,12 @@ export declare namespace keyManager { * ```ts * import { createClient, http } from 'viem' * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Handler } from 'tempo.ts/server' * * const client = createClient({ * account: privateKeyToAccount('0x...'), - * chain: tempo({ + * chain: tempoTestnet.extend({ * feeToken: '0x20c0000000000000000000000000000000000001', * }), * transport: http(), @@ -469,11 +468,11 @@ export declare namespace keyManager { * ```ts * import { createClient, http } from 'viem' * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Handler } from 'tempo.ts/server' * * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), + * chain: tempoTestnet.extend({ feeToken: '0x20c0000000000000000000000000000000000001' }), * transport: http(), * }) * @@ -491,11 +490,11 @@ export declare namespace keyManager { * ```ts * import { createClient, http } from 'viem' * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Handler } from 'tempo.ts/server' * * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), + * chain: tempoTestnet.extend({ feeToken: '0x20c0000000000000000000000000000000000001' }), * transport: http(), * }) * @@ -534,7 +533,7 @@ export function feePayer(options: feePayer.Options) { await onRequest?.(request) if (request.method === 'eth_signTransaction') { - const transactionRequest = formatTransaction( + const transactionRequest = Formatters.formatTransaction( request.params?.[0] as never, ) diff --git a/src/viem/Abis.ts b/src/viem/Abis.ts deleted file mode 100644 index dd85ea38..00000000 --- a/src/viem/Abis.ts +++ /dev/null @@ -1,1688 +0,0 @@ -// Generated with `pnpm gen:abis`. Do not modify manually. - -export const accountKeychain = [ - { - name: 'authorizeKey', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'keyId' }, - { type: 'uint8', name: 'signatureType' }, - { type: 'uint64', name: 'expiry' }, - { type: 'bool', name: 'enforceLimits' }, - { - type: 'tuple[]', - name: 'limits', - components: [ - { type: 'address', name: 'token' }, - { type: 'uint256', name: 'amount' }, - ], - }, - ], - outputs: [], - }, - { - name: 'revokeKey', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'address', name: 'keyId' }], - outputs: [], - }, - { - name: 'updateSpendingLimit', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'keyId' }, - { type: 'address', name: 'token' }, - { type: 'uint256', name: 'newLimit' }, - ], - outputs: [], - }, - { - name: 'getKey', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'address', name: 'account' }, - { type: 'address', name: 'keyId' }, - ], - outputs: [ - { - type: 'tuple', - components: [ - { type: 'uint8', name: 'signatureType' }, - { type: 'address', name: 'keyId' }, - { type: 'uint64', name: 'expiry' }, - { type: 'bool', name: 'enforceLimits' }, - { type: 'bool', name: 'isRevoked' }, - ], - }, - ], - }, - { - name: 'getRemainingLimit', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'address', name: 'account' }, - { type: 'address', name: 'keyId' }, - { type: 'address', name: 'token' }, - ], - outputs: [{ type: 'uint256' }], - }, - { - name: 'getTransactionKey', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'address' }], - }, - { - name: 'KeyAuthorized', - type: 'event', - inputs: [ - { type: 'address', name: 'account', indexed: true }, - { type: 'bytes32', name: 'publicKey', indexed: true }, - { type: 'uint8', name: 'signatureType' }, - { type: 'uint64', name: 'expiry' }, - ], - }, - { - name: 'KeyRevoked', - type: 'event', - inputs: [ - { type: 'address', name: 'account', indexed: true }, - { type: 'bytes32', name: 'publicKey', indexed: true }, - ], - }, - { - name: 'SpendingLimitUpdated', - type: 'event', - inputs: [ - { type: 'address', name: 'account', indexed: true }, - { type: 'bytes32', name: 'publicKey', indexed: true }, - { type: 'address', name: 'token', indexed: true }, - { type: 'uint256', name: 'newLimit' }, - ], - }, - { name: 'UnauthorizedCaller', type: 'error', inputs: [] }, - { name: 'KeyAlreadyExists', type: 'error', inputs: [] }, - { name: 'KeyNotFound', type: 'error', inputs: [] }, - { name: 'KeyExpired', type: 'error', inputs: [] }, - { name: 'SpendingLimitExceeded', type: 'error', inputs: [] }, - { name: 'InvalidSignatureType', type: 'error', inputs: [] }, - { name: 'ZeroPublicKey', type: 'error', inputs: [] }, - { name: 'ExpiryInPast', type: 'error', inputs: [] }, - { name: 'KeyAlreadyRevoked', type: 'error', inputs: [] }, -] as const - -export const nonce = [ - { - name: 'getNonce', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'address', name: 'account' }, - { type: 'uint256', name: 'nonceKey' }, - ], - outputs: [{ type: 'uint64', name: 'nonce' }], - }, - { - name: 'getActiveNonceKeyCount', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'address', name: 'account' }], - outputs: [{ type: 'uint256', name: 'count' }], - }, - { - name: 'NonceIncremented', - type: 'event', - inputs: [ - { type: 'address', name: 'account', indexed: true }, - { type: 'uint256', name: 'nonceKey', indexed: true }, - { type: 'uint64', name: 'newNonce' }, - ], - }, - { - name: 'ActiveKeyCountChanged', - type: 'event', - inputs: [ - { type: 'address', name: 'account', indexed: true }, - { type: 'uint256', name: 'newCount' }, - ], - }, - { name: 'ProtocolNonceNotSupported', type: 'error', inputs: [] }, - { name: 'InvalidNonceKey', type: 'error', inputs: [] }, - { name: 'NonceOverflow', type: 'error', inputs: [] }, -] as const - -export const pathUsd = [ - { - name: 'TRANSFER_ROLE', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'bytes32' }], - }, - { - name: 'RECEIVE_WITH_MEMO_ROLE', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'bytes32' }], - }, -] as const - -export const stablecoinExchange = [ - { - name: 'createPair', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'address', name: 'base' }], - outputs: [{ type: 'bytes32', name: 'key' }], - }, - { - name: 'place', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'token' }, - { type: 'uint128', name: 'amount' }, - { type: 'bool', name: 'isBid' }, - { type: 'int16', name: 'tick' }, - ], - outputs: [{ type: 'uint128', name: 'orderId' }], - }, - { - name: 'placeFlip', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'token' }, - { type: 'uint128', name: 'amount' }, - { type: 'bool', name: 'isBid' }, - { type: 'int16', name: 'tick' }, - { type: 'int16', name: 'flipTick' }, - ], - outputs: [{ type: 'uint128', name: 'orderId' }], - }, - { - name: 'cancel', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'uint128', name: 'orderId' }], - outputs: [], - }, - { - name: 'executeBlock', - type: 'function', - stateMutability: 'nonpayable', - inputs: [], - outputs: [], - }, - { - name: 'swapExactAmountIn', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'tokenIn' }, - { type: 'address', name: 'tokenOut' }, - { type: 'uint128', name: 'amountIn' }, - { type: 'uint128', name: 'minAmountOut' }, - ], - outputs: [{ type: 'uint128', name: 'amountOut' }], - }, - { - name: 'swapExactAmountOut', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'tokenIn' }, - { type: 'address', name: 'tokenOut' }, - { type: 'uint128', name: 'amountOut' }, - { type: 'uint128', name: 'maxAmountIn' }, - ], - outputs: [{ type: 'uint128', name: 'amountIn' }], - }, - { - name: 'quoteSwapExactAmountIn', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'address', name: 'tokenIn' }, - { type: 'address', name: 'tokenOut' }, - { type: 'uint128', name: 'amountIn' }, - ], - outputs: [{ type: 'uint128', name: 'amountOut' }], - }, - { - name: 'quoteSwapExactAmountOut', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'address', name: 'tokenIn' }, - { type: 'address', name: 'tokenOut' }, - { type: 'uint128', name: 'amountOut' }, - ], - outputs: [{ type: 'uint128', name: 'amountIn' }], - }, - { - name: 'balanceOf', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'address', name: 'user' }, - { type: 'address', name: 'token' }, - ], - outputs: [{ type: 'uint128' }], - }, - { - name: 'withdraw', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'token' }, - { type: 'uint128', name: 'amount' }, - ], - outputs: [], - }, - { - name: 'getOrder', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'uint128', name: 'orderId' }], - outputs: [ - { - type: 'tuple', - components: [ - { type: 'uint128', name: 'orderId' }, - { type: 'address', name: 'maker' }, - { type: 'bytes32', name: 'bookKey' }, - { type: 'bool', name: 'isBid' }, - { type: 'int16', name: 'tick' }, - { type: 'uint128', name: 'amount' }, - { type: 'uint128', name: 'remaining' }, - { type: 'uint128', name: 'prev' }, - { type: 'uint128', name: 'next' }, - { type: 'bool', name: 'isFlip' }, - { type: 'int16', name: 'flipTick' }, - ], - }, - ], - }, - { - name: 'getTickLevel', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'address', name: 'base' }, - { type: 'int16', name: 'tick' }, - { type: 'bool', name: 'isBid' }, - ], - outputs: [ - { type: 'uint128', name: 'head' }, - { type: 'uint128', name: 'tail' }, - { type: 'uint128', name: 'totalLiquidity' }, - ], - }, - { - name: 'pairKey', - type: 'function', - stateMutability: 'pure', - inputs: [ - { type: 'address', name: 'tokenA' }, - { type: 'address', name: 'tokenB' }, - ], - outputs: [{ type: 'bytes32' }], - }, - { - name: 'activeOrderId', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint128' }], - }, - { - name: 'pendingOrderId', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint128' }], - }, - { - name: 'books', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'bytes32', name: 'pairKey' }], - outputs: [ - { - type: 'tuple', - components: [ - { type: 'address', name: 'base' }, - { type: 'address', name: 'quote' }, - { type: 'int16', name: 'bestBidTick' }, - { type: 'int16', name: 'bestAskTick' }, - ], - }, - ], - }, - { - name: 'MIN_TICK', - type: 'function', - stateMutability: 'pure', - inputs: [], - outputs: [{ type: 'int16' }], - }, - { - name: 'MAX_TICK', - type: 'function', - stateMutability: 'pure', - inputs: [], - outputs: [{ type: 'int16' }], - }, - { - name: 'TICK_SPACING', - type: 'function', - stateMutability: 'pure', - inputs: [], - outputs: [{ type: 'int16' }], - }, - { - name: 'PRICE_SCALE', - type: 'function', - stateMutability: 'pure', - inputs: [], - outputs: [{ type: 'uint32' }], - }, - { - name: 'MIN_PRICE', - type: 'function', - stateMutability: 'pure', - inputs: [], - outputs: [{ type: 'uint32' }], - }, - { - name: 'MAX_PRICE', - type: 'function', - stateMutability: 'pure', - inputs: [], - outputs: [{ type: 'uint32' }], - }, - { - name: 'tickToPrice', - type: 'function', - stateMutability: 'pure', - inputs: [{ type: 'int16', name: 'tick' }], - outputs: [{ type: 'uint32', name: 'price' }], - }, - { - name: 'priceToTick', - type: 'function', - stateMutability: 'pure', - inputs: [{ type: 'uint32', name: 'price' }], - outputs: [{ type: 'int16', name: 'tick' }], - }, - { - name: 'PairCreated', - type: 'event', - inputs: [ - { type: 'bytes32', name: 'key', indexed: true }, - { type: 'address', name: 'base', indexed: true }, - { type: 'address', name: 'quote', indexed: true }, - ], - }, - { - name: 'OrderPlaced', - type: 'event', - inputs: [ - { type: 'uint128', name: 'orderId', indexed: true }, - { type: 'address', name: 'maker', indexed: true }, - { type: 'address', name: 'token', indexed: true }, - { type: 'uint128', name: 'amount' }, - { type: 'bool', name: 'isBid' }, - { type: 'int16', name: 'tick' }, - ], - }, - { - name: 'FlipOrderPlaced', - type: 'event', - inputs: [ - { type: 'uint128', name: 'orderId', indexed: true }, - { type: 'address', name: 'maker', indexed: true }, - { type: 'address', name: 'token', indexed: true }, - { type: 'uint128', name: 'amount' }, - { type: 'bool', name: 'isBid' }, - { type: 'int16', name: 'tick' }, - { type: 'int16', name: 'flipTick' }, - ], - }, - { - name: 'OrderFilled', - type: 'event', - inputs: [ - { type: 'uint128', name: 'orderId', indexed: true }, - { type: 'address', name: 'maker', indexed: true }, - { type: 'uint128', name: 'amountFilled' }, - { type: 'bool', name: 'partialFill' }, - ], - }, - { - name: 'OrderFilled', - type: 'event', - inputs: [ - { type: 'uint128', name: 'orderId', indexed: true }, - { type: 'address', name: 'maker', indexed: true }, - { type: 'address', name: 'taker', indexed: true }, - { type: 'uint128', name: 'amountFilled' }, - { type: 'bool', name: 'partialFill' }, - ], - }, - { - name: 'OrderCancelled', - type: 'event', - inputs: [{ type: 'uint128', name: 'orderId', indexed: true }], - }, - { name: 'Unauthorized', type: 'error', inputs: [] }, - { name: 'PairDoesNotExist', type: 'error', inputs: [] }, - { name: 'PairAlreadyExists', type: 'error', inputs: [] }, - { name: 'OrderDoesNotExist', type: 'error', inputs: [] }, - { name: 'IdenticalTokens', type: 'error', inputs: [] }, - { name: 'InvalidToken', type: 'error', inputs: [] }, - { - name: 'TickOutOfBounds', - type: 'error', - inputs: [{ type: 'int16', name: 'tick' }], - }, - { name: 'InvalidTick', type: 'error', inputs: [] }, - { name: 'InvalidFlipTick', type: 'error', inputs: [] }, - { name: 'InsufficientBalance', type: 'error', inputs: [] }, - { name: 'InsufficientLiquidity', type: 'error', inputs: [] }, - { name: 'InsufficientOutput', type: 'error', inputs: [] }, - { name: 'MaxInputExceeded', type: 'error', inputs: [] }, - { - name: 'BelowMinimumOrderSize', - type: 'error', - inputs: [{ type: 'uint128', name: 'amount' }], - }, - { name: 'InvalidBaseToken', type: 'error', inputs: [] }, -] as const - -export const tip20 = [ - { - name: 'name', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'string' }], - }, - { - name: 'symbol', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'string' }], - }, - { - name: 'decimals', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint8' }], - }, - { - name: 'totalSupply', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint256' }], - }, - { - name: 'quoteToken', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'address' }], - }, - { - name: 'nextQuoteToken', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'address' }], - }, - { - name: 'balanceOf', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'address', name: 'account' }], - outputs: [{ type: 'uint256' }], - }, - { - name: 'transfer', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'to' }, - { type: 'uint256', name: 'amount' }, - ], - outputs: [{ type: 'bool' }], - }, - { - name: 'approve', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'spender' }, - { type: 'uint256', name: 'amount' }, - ], - outputs: [{ type: 'bool' }], - }, - { - name: 'allowance', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'address', name: 'owner' }, - { type: 'address', name: 'spender' }, - ], - outputs: [{ type: 'uint256' }], - }, - { - name: 'transferFrom', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'from' }, - { type: 'address', name: 'to' }, - { type: 'uint256', name: 'amount' }, - ], - outputs: [{ type: 'bool' }], - }, - { - name: 'mint', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'to' }, - { type: 'uint256', name: 'amount' }, - ], - outputs: [], - }, - { - name: 'burn', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'uint256', name: 'amount' }], - outputs: [], - }, - { - name: 'currency', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'string' }], - }, - { - name: 'supplyCap', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint256' }], - }, - { - name: 'paused', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'bool' }], - }, - { - name: 'transferPolicyId', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint64' }], - }, - { - name: 'burnBlocked', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'from' }, - { type: 'uint256', name: 'amount' }, - ], - outputs: [], - }, - { - name: 'mintWithMemo', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'to' }, - { type: 'uint256', name: 'amount' }, - { type: 'bytes32', name: 'memo' }, - ], - outputs: [], - }, - { - name: 'burnWithMemo', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'uint256', name: 'amount' }, - { type: 'bytes32', name: 'memo' }, - ], - outputs: [], - }, - { - name: 'transferWithMemo', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'to' }, - { type: 'uint256', name: 'amount' }, - { type: 'bytes32', name: 'memo' }, - ], - outputs: [], - }, - { - name: 'transferFromWithMemo', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'from' }, - { type: 'address', name: 'to' }, - { type: 'uint256', name: 'amount' }, - { type: 'bytes32', name: 'memo' }, - ], - outputs: [{ type: 'bool' }], - }, - { - name: 'feeRecipient', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'address' }], - }, - { - name: 'setFeeRecipient', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'address', name: 'newRecipient' }], - outputs: [{ type: 'address' }], - }, - { - name: 'changeTransferPolicyId', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'uint64', name: 'newPolicyId' }], - outputs: [], - }, - { - name: 'setSupplyCap', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'uint256', name: 'newSupplyCap' }], - outputs: [], - }, - { - name: 'pause', - type: 'function', - stateMutability: 'nonpayable', - inputs: [], - outputs: [], - }, - { - name: 'unpause', - type: 'function', - stateMutability: 'nonpayable', - inputs: [], - outputs: [], - }, - { - name: 'setNextQuoteToken', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'address', name: 'newQuoteToken' }], - outputs: [], - }, - { - name: 'completeQuoteTokenUpdate', - type: 'function', - stateMutability: 'nonpayable', - inputs: [], - outputs: [], - }, - { - name: 'PAUSE_ROLE', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'bytes32' }], - }, - { - name: 'UNPAUSE_ROLE', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'bytes32' }], - }, - { - name: 'ISSUER_ROLE', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'bytes32' }], - }, - { - name: 'BURN_BLOCKED_ROLE', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'bytes32' }], - }, - { - name: 'startReward', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'uint256', name: 'amount' }, - { type: 'uint32', name: 'secs' }, - ], - outputs: [{ type: 'uint64' }], - }, - { - name: 'setRewardRecipient', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'address', name: 'recipient' }], - outputs: [], - }, - { - name: 'cancelReward', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'uint64', name: 'id' }], - outputs: [{ type: 'uint256' }], - }, - { - name: 'claimRewards', - type: 'function', - stateMutability: 'nonpayable', - inputs: [], - outputs: [{ type: 'uint256' }], - }, - { - name: 'finalizeStreams', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'uint64', name: 'timestamp' }], - outputs: [], - }, - { - name: 'getStream', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'uint64', name: 'id' }], - outputs: [ - { - type: 'tuple', - components: [ - { type: 'address', name: 'funder' }, - { type: 'uint64', name: 'startTime' }, - { type: 'uint64', name: 'endTime' }, - { type: 'uint256', name: 'ratePerSecondScaled' }, - { type: 'uint256', name: 'amountTotal' }, - ], - }, - ], - }, - { - name: 'totalRewardPerSecond', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint256' }], - }, - { - name: 'optedInSupply', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint128' }], - }, - { - name: 'nextStreamId', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint64' }], - }, - { - name: 'userRewardInfo', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'address', name: 'account' }], - outputs: [ - { - type: 'tuple', - components: [ - { type: 'address', name: 'rewardRecipient' }, - { type: 'uint256', name: 'rewardPerToken' }, - { type: 'uint256', name: 'rewardBalance' }, - ], - }, - ], - }, - { - name: 'Transfer', - type: 'event', - inputs: [ - { type: 'address', name: 'from', indexed: true }, - { type: 'address', name: 'to', indexed: true }, - { type: 'uint256', name: 'amount' }, - ], - }, - { - name: 'Approval', - type: 'event', - inputs: [ - { type: 'address', name: 'owner', indexed: true }, - { type: 'address', name: 'spender', indexed: true }, - { type: 'uint256', name: 'amount' }, - ], - }, - { - name: 'Mint', - type: 'event', - inputs: [ - { type: 'address', name: 'to', indexed: true }, - { type: 'uint256', name: 'amount' }, - ], - }, - { - name: 'Burn', - type: 'event', - inputs: [ - { type: 'address', name: 'from', indexed: true }, - { type: 'uint256', name: 'amount' }, - ], - }, - { - name: 'BurnBlocked', - type: 'event', - inputs: [ - { type: 'address', name: 'from', indexed: true }, - { type: 'uint256', name: 'amount' }, - ], - }, - { - name: 'TransferWithMemo', - type: 'event', - inputs: [ - { type: 'address', name: 'from', indexed: true }, - { type: 'address', name: 'to', indexed: true }, - { type: 'uint256', name: 'amount' }, - { type: 'bytes32', name: 'memo', indexed: true }, - ], - }, - { - name: 'TransferPolicyUpdate', - type: 'event', - inputs: [ - { type: 'address', name: 'updater', indexed: true }, - { type: 'uint64', name: 'newPolicyId', indexed: true }, - ], - }, - { - name: 'SupplyCapUpdate', - type: 'event', - inputs: [ - { type: 'address', name: 'updater', indexed: true }, - { type: 'uint256', name: 'newSupplyCap', indexed: true }, - ], - }, - { - name: 'PauseStateUpdate', - type: 'event', - inputs: [ - { type: 'address', name: 'updater', indexed: true }, - { type: 'bool', name: 'isPaused' }, - ], - }, - { - name: 'NextQuoteTokenSet', - type: 'event', - inputs: [ - { type: 'address', name: 'updater', indexed: true }, - { type: 'address', name: 'nextQuoteToken', indexed: true }, - ], - }, - { - name: 'QuoteTokenUpdate', - type: 'event', - inputs: [ - { type: 'address', name: 'updater', indexed: true }, - { type: 'address', name: 'newQuoteToken', indexed: true }, - ], - }, - { - name: 'RewardScheduled', - type: 'event', - inputs: [ - { type: 'address', name: 'funder', indexed: true }, - { type: 'uint64', name: 'id', indexed: true }, - { type: 'uint256', name: 'amount' }, - { type: 'uint32', name: 'durationSeconds' }, - ], - }, - { - name: 'RewardCanceled', - type: 'event', - inputs: [ - { type: 'address', name: 'funder', indexed: true }, - { type: 'uint64', name: 'id', indexed: true }, - { type: 'uint256', name: 'refund' }, - ], - }, - { - name: 'RewardRecipientSet', - type: 'event', - inputs: [ - { type: 'address', name: 'holder', indexed: true }, - { type: 'address', name: 'recipient', indexed: true }, - ], - }, - { - name: 'FeeRecipientUpdated', - type: 'event', - inputs: [ - { type: 'address', name: 'updater', indexed: true }, - { type: 'address', name: 'newRecipient', indexed: true }, - ], - }, - { - name: 'InsufficientBalance', - type: 'error', - inputs: [ - { type: 'uint256', name: 'available' }, - { type: 'uint256', name: 'required' }, - { type: 'address', name: 'token' }, - ], - }, - { name: 'InsufficientAllowance', type: 'error', inputs: [] }, - { name: 'SupplyCapExceeded', type: 'error', inputs: [] }, - { name: 'InvalidSupplyCap', type: 'error', inputs: [] }, - { name: 'InvalidPayload', type: 'error', inputs: [] }, - { name: 'StringTooLong', type: 'error', inputs: [] }, - { name: 'PolicyForbids', type: 'error', inputs: [] }, - { name: 'InvalidRecipient', type: 'error', inputs: [] }, - { name: 'ContractPaused', type: 'error', inputs: [] }, - { name: 'InvalidCurrency', type: 'error', inputs: [] }, - { name: 'InvalidQuoteToken', type: 'error', inputs: [] }, - { name: 'TransfersDisabled', type: 'error', inputs: [] }, - { name: 'InvalidAmount', type: 'error', inputs: [] }, - { name: 'NotStreamFunder', type: 'error', inputs: [] }, - { name: 'StreamInactive', type: 'error', inputs: [] }, - { name: 'NoOptedInSupply', type: 'error', inputs: [] }, - { name: 'Unauthorized', type: 'error', inputs: [] }, - { name: 'RewardsDisabled', type: 'error', inputs: [] }, - { name: 'ScheduledRewardsDisabled', type: 'error', inputs: [] }, - { name: 'ProtectedAddress', type: 'error', inputs: [] }, - { - name: 'hasRole', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'address', name: 'account' }, - { type: 'bytes32', name: 'role' }, - ], - outputs: [{ type: 'bool' }], - }, - { - name: 'getRoleAdmin', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'bytes32', name: 'role' }], - outputs: [{ type: 'bytes32' }], - }, - { - name: 'grantRole', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'bytes32', name: 'role' }, - { type: 'address', name: 'account' }, - ], - outputs: [], - }, - { - name: 'revokeRole', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'bytes32', name: 'role' }, - { type: 'address', name: 'account' }, - ], - outputs: [], - }, - { - name: 'renounceRole', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'bytes32', name: 'role' }], - outputs: [], - }, - { - name: 'setRoleAdmin', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'bytes32', name: 'role' }, - { type: 'bytes32', name: 'adminRole' }, - ], - outputs: [], - }, - { - name: 'RoleMembershipUpdated', - type: 'event', - inputs: [ - { type: 'bytes32', name: 'role', indexed: true }, - { type: 'address', name: 'account', indexed: true }, - { type: 'address', name: 'sender', indexed: true }, - { type: 'bool', name: 'hasRole' }, - ], - }, - { - name: 'RoleAdminUpdated', - type: 'event', - inputs: [ - { type: 'bytes32', name: 'role', indexed: true }, - { type: 'bytes32', name: 'newAdminRole', indexed: true }, - { type: 'address', name: 'sender', indexed: true }, - ], - }, - { name: 'Unauthorized', type: 'error', inputs: [] }, -] as const - -export const tip20Factory = [ - { - name: 'createToken', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'string', name: 'name' }, - { type: 'string', name: 'symbol' }, - { type: 'string', name: 'currency' }, - { type: 'address', name: 'quoteToken' }, - { type: 'address', name: 'admin' }, - ], - outputs: [{ type: 'address' }], - }, - { - name: 'tokenIdCounter', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint256' }], - }, - { - name: 'isTIP20', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'address', name: 'token' }], - outputs: [{ type: 'bool' }], - }, - { - name: 'TokenCreated', - type: 'event', - inputs: [ - { type: 'address', name: 'token', indexed: true }, - { type: 'uint256', name: 'tokenId', indexed: true }, - { type: 'string', name: 'name' }, - { type: 'string', name: 'symbol' }, - { type: 'string', name: 'currency' }, - { type: 'address', name: 'quoteToken' }, - { type: 'address', name: 'admin' }, - ], - }, -] as const - -export const tip20RewardsRegistry = [ - { - name: 'finalizeStreams', - type: 'function', - stateMutability: 'nonpayable', - inputs: [], - outputs: [], - }, - { name: 'Unauthorized', type: 'error', inputs: [] }, - { name: 'StreamsAlreadyFinalized', type: 'error', inputs: [] }, -] as const - -export const tip403Registry = [ - { - name: 'policyIdCounter', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint64' }], - }, - { - name: 'policyData', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'uint64', name: 'policyId' }], - outputs: [ - { type: 'uint8', name: 'policyType' }, - { type: 'address', name: 'admin' }, - ], - }, - { - name: 'isAuthorized', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'uint64', name: 'policyId' }, - { type: 'address', name: 'user' }, - ], - outputs: [{ type: 'bool' }], - }, - { - name: 'createPolicy', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'admin' }, - { type: 'uint8', name: 'policyType' }, - ], - outputs: [{ type: 'uint64' }], - }, - { - name: 'createPolicyWithAccounts', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'admin' }, - { type: 'uint8', name: 'policyType' }, - { type: 'address[]', name: 'accounts' }, - ], - outputs: [{ type: 'uint64' }], - }, - { - name: 'setPolicyAdmin', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'uint64', name: 'policyId' }, - { type: 'address', name: 'admin' }, - ], - outputs: [], - }, - { - name: 'modifyPolicyWhitelist', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'uint64', name: 'policyId' }, - { type: 'address', name: 'account' }, - { type: 'bool', name: 'allowed' }, - ], - outputs: [], - }, - { - name: 'modifyPolicyBlacklist', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'uint64', name: 'policyId' }, - { type: 'address', name: 'account' }, - { type: 'bool', name: 'restricted' }, - ], - outputs: [], - }, - { - name: 'PolicyAdminUpdated', - type: 'event', - inputs: [ - { type: 'uint64', name: 'policyId', indexed: true }, - { type: 'address', name: 'updater', indexed: true }, - { type: 'address', name: 'admin', indexed: true }, - ], - }, - { - name: 'PolicyCreated', - type: 'event', - inputs: [ - { type: 'uint64', name: 'policyId', indexed: true }, - { type: 'address', name: 'updater', indexed: true }, - { type: 'uint8', name: 'policyType' }, - ], - }, - { - name: 'WhitelistUpdated', - type: 'event', - inputs: [ - { type: 'uint64', name: 'policyId', indexed: true }, - { type: 'address', name: 'updater', indexed: true }, - { type: 'address', name: 'account', indexed: true }, - { type: 'bool', name: 'allowed' }, - ], - }, - { - name: 'BlacklistUpdated', - type: 'event', - inputs: [ - { type: 'uint64', name: 'policyId', indexed: true }, - { type: 'address', name: 'updater', indexed: true }, - { type: 'address', name: 'account', indexed: true }, - { type: 'bool', name: 'restricted' }, - ], - }, - { name: 'Unauthorized', type: 'error', inputs: [] }, - { name: 'IncompatiblePolicyType', type: 'error', inputs: [] }, - { name: 'SelfOwnedPolicyMustBeWhitelist', type: 'error', inputs: [] }, -] as const - -export const tipAccountRegistrar = [ - { - name: 'delegateToDefault', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'bytes32', name: 'hash' }, - { type: 'bytes', name: 'signature' }, - ], - outputs: [{ type: 'address', name: 'authority' }], - }, - { - name: 'delegateToDefault', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'bytes', name: 'message' }, - { type: 'bytes', name: 'signature' }, - ], - outputs: [{ type: 'address', name: 'authority' }], - }, - { name: 'InvalidSignature', type: 'error', inputs: [] }, - { name: 'CodeNotEmpty', type: 'error', inputs: [] }, - { name: 'NonceNotZero', type: 'error', inputs: [] }, -] as const - -export const feeManager = [ - { - name: 'userTokens', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'address', name: 'user' }], - outputs: [{ type: 'address' }], - }, - { - name: 'validatorTokens', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'address', name: 'validator' }], - outputs: [{ type: 'address' }], - }, - { - name: 'setUserToken', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'address', name: 'token' }], - outputs: [], - }, - { - name: 'setValidatorToken', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'address', name: 'token' }], - outputs: [], - }, - { - name: 'getFeeTokenBalance', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'address', name: 'sender' }, - { type: 'address', name: 'validator' }, - ], - outputs: [{ type: 'address' }, { type: 'uint256' }], - }, - { - name: 'executeBlock', - type: 'function', - stateMutability: 'nonpayable', - inputs: [], - outputs: [], - }, - { - name: 'UserTokenSet', - type: 'event', - inputs: [ - { type: 'address', name: 'user', indexed: true }, - { type: 'address', name: 'token', indexed: true }, - ], - }, - { - name: 'ValidatorTokenSet', - type: 'event', - inputs: [ - { type: 'address', name: 'validator', indexed: true }, - { type: 'address', name: 'token', indexed: true }, - ], - }, - { name: 'OnlyValidator', type: 'error', inputs: [] }, - { name: 'OnlySystemContract', type: 'error', inputs: [] }, - { name: 'InvalidToken', type: 'error', inputs: [] }, - { name: 'PoolDoesNotExist', type: 'error', inputs: [] }, - { name: 'InsufficientFeeTokenBalance', type: 'error', inputs: [] }, - { name: 'InternalError', type: 'error', inputs: [] }, - { name: 'CannotChangeWithinBlock', type: 'error', inputs: [] }, - { name: 'CannotChangeWithPendingFees', type: 'error', inputs: [] }, - { name: 'TokenPolicyForbids', type: 'error', inputs: [] }, -] as const - -export const feeAmm = [ - { - name: 'M', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint256' }], - }, - { - name: 'N', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint256' }], - }, - { - name: 'SCALE', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint256' }], - }, - { - name: 'MIN_LIQUIDITY', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'uint256' }], - }, - { - name: 'getPoolId', - type: 'function', - stateMutability: 'pure', - inputs: [ - { type: 'address', name: 'userToken' }, - { type: 'address', name: 'validatorToken' }, - ], - outputs: [{ type: 'bytes32' }], - }, - { - name: 'getPool', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'address', name: 'userToken' }, - { type: 'address', name: 'validatorToken' }, - ], - outputs: [ - { - type: 'tuple', - components: [ - { type: 'uint128', name: 'reserveUserToken' }, - { type: 'uint128', name: 'reserveValidatorToken' }, - ], - }, - ], - }, - { - name: 'pools', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'bytes32', name: 'poolId' }], - outputs: [ - { - type: 'tuple', - components: [ - { type: 'uint128', name: 'reserveUserToken' }, - { type: 'uint128', name: 'reserveValidatorToken' }, - ], - }, - ], - }, - { - name: 'mint', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'userToken' }, - { type: 'address', name: 'validatorToken' }, - { type: 'uint256', name: 'amountUserToken' }, - { type: 'uint256', name: 'amountValidatorToken' }, - { type: 'address', name: 'to' }, - ], - outputs: [{ type: 'uint256', name: 'liquidity' }], - }, - { - name: 'mintWithValidatorToken', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'userToken' }, - { type: 'address', name: 'validatorToken' }, - { type: 'uint256', name: 'amountValidatorToken' }, - { type: 'address', name: 'to' }, - ], - outputs: [{ type: 'uint256', name: 'liquidity' }], - }, - { - name: 'burn', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'userToken' }, - { type: 'address', name: 'validatorToken' }, - { type: 'uint256', name: 'liquidity' }, - { type: 'address', name: 'to' }, - ], - outputs: [ - { type: 'uint256', name: 'amountUserToken' }, - { type: 'uint256', name: 'amountValidatorToken' }, - ], - }, - { - name: 'totalSupply', - type: 'function', - stateMutability: 'view', - inputs: [{ type: 'bytes32', name: 'poolId' }], - outputs: [{ type: 'uint256' }], - }, - { - name: 'liquidityBalances', - type: 'function', - stateMutability: 'view', - inputs: [ - { type: 'bytes32', name: 'poolId' }, - { type: 'address', name: 'user' }, - ], - outputs: [{ type: 'uint256' }], - }, - { - name: 'rebalanceSwap', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'userToken' }, - { type: 'address', name: 'validatorToken' }, - { type: 'uint256', name: 'amountOut' }, - { type: 'address', name: 'to' }, - ], - outputs: [{ type: 'uint256', name: 'amountIn' }], - }, - { - name: 'Mint', - type: 'event', - inputs: [ - { type: 'address', name: 'sender', indexed: true }, - { type: 'address', name: 'userToken', indexed: true }, - { type: 'address', name: 'validatorToken', indexed: true }, - { type: 'uint256', name: 'amountUserToken' }, - { type: 'uint256', name: 'amountValidatorToken' }, - { type: 'uint256', name: 'liquidity' }, - ], - }, - { - name: 'Burn', - type: 'event', - inputs: [ - { type: 'address', name: 'sender', indexed: true }, - { type: 'address', name: 'userToken', indexed: true }, - { type: 'address', name: 'validatorToken', indexed: true }, - { type: 'uint256', name: 'amountUserToken' }, - { type: 'uint256', name: 'amountValidatorToken' }, - { type: 'uint256', name: 'liquidity' }, - { type: 'address', name: 'to' }, - ], - }, - { - name: 'RebalanceSwap', - type: 'event', - inputs: [ - { type: 'address', name: 'userToken', indexed: true }, - { type: 'address', name: 'validatorToken', indexed: true }, - { type: 'address', name: 'swapper', indexed: true }, - { type: 'uint256', name: 'amountIn' }, - { type: 'uint256', name: 'amountOut' }, - ], - }, - { - name: 'FeeSwap', - type: 'event', - inputs: [ - { type: 'address', name: 'userToken', indexed: true }, - { type: 'address', name: 'validatorToken', indexed: true }, - { type: 'uint256', name: 'amountIn' }, - { type: 'uint256', name: 'amountOut' }, - ], - }, - { name: 'IdenticalAddresses', type: 'error', inputs: [] }, - { name: 'ZeroAddress', type: 'error', inputs: [] }, - { name: 'PoolExists', type: 'error', inputs: [] }, - { name: 'PoolDoesNotExist', type: 'error', inputs: [] }, - { name: 'InvalidToken', type: 'error', inputs: [] }, - { name: 'InsufficientLiquidity', type: 'error', inputs: [] }, - { name: 'OnlyProtocol', type: 'error', inputs: [] }, - { name: 'InsufficientPoolBalance', type: 'error', inputs: [] }, - { name: 'InsufficientReserves', type: 'error', inputs: [] }, - { name: 'InsufficientLiquidityBalance', type: 'error', inputs: [] }, - { name: 'MustDepositLowerBalanceToken', type: 'error', inputs: [] }, - { name: 'InvalidAmount', type: 'error', inputs: [] }, - { name: 'InvalidRebalanceState', type: 'error', inputs: [] }, - { name: 'InvalidRebalanceDirection', type: 'error', inputs: [] }, - { name: 'InvalidNewReserves', type: 'error', inputs: [] }, - { name: 'CannotSupportPendingSwaps', type: 'error', inputs: [] }, - { name: 'DivisionByZero', type: 'error', inputs: [] }, - { name: 'InvalidSwapCalculation', type: 'error', inputs: [] }, - { name: 'InsufficientLiquidityForPending', type: 'error', inputs: [] }, - { name: 'TokenTransferFailed', type: 'error', inputs: [] }, - { name: 'InternalError', type: 'error', inputs: [] }, -] as const - -export const validatorConfig = [ - { - name: 'getValidators', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [ - { - type: 'tuple[]', - name: 'validators', - components: [ - { type: 'bytes32', name: 'publicKey' }, - { type: 'bool', name: 'active' }, - { type: 'uint64', name: 'index' }, - { type: 'address', name: 'validatorAddress' }, - { type: 'string', name: 'inboundAddress' }, - { type: 'string', name: 'outboundAddress' }, - ], - }, - ], - }, - { - name: 'addValidator', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'newValidatorAddress' }, - { type: 'bytes32', name: 'publicKey' }, - { type: 'bool', name: 'active' }, - { type: 'string', name: 'inboundAddress' }, - { type: 'string', name: 'outboundAddress' }, - ], - outputs: [], - }, - { - name: 'updateValidator', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'newValidatorAddress' }, - { type: 'bytes32', name: 'publicKey' }, - { type: 'string', name: 'inboundAddress' }, - { type: 'string', name: 'outboundAddress' }, - ], - outputs: [], - }, - { - name: 'changeValidatorStatus', - type: 'function', - stateMutability: 'nonpayable', - inputs: [ - { type: 'address', name: 'validator' }, - { type: 'bool', name: 'active' }, - ], - outputs: [], - }, - { - name: 'owner', - type: 'function', - stateMutability: 'view', - inputs: [], - outputs: [{ type: 'address' }], - }, - { - name: 'changeOwner', - type: 'function', - stateMutability: 'nonpayable', - inputs: [{ type: 'address', name: 'newOwner' }], - outputs: [], - }, - { name: 'Unauthorized', type: 'error', inputs: [] }, - { name: 'ValidatorAlreadyExists', type: 'error', inputs: [] }, - { name: 'ValidatorNotFound', type: 'error', inputs: [] }, - { - name: 'NotHostPort', - type: 'error', - inputs: [ - { type: 'string', name: 'field' }, - { type: 'string', name: 'input' }, - { type: 'string', name: 'backtrace' }, - ], - }, - { - name: 'NotIpPort', - type: 'error', - inputs: [ - { type: 'string', name: 'field' }, - { type: 'string', name: 'input' }, - { type: 'string', name: 'backtrace' }, - ], - }, -] as const diff --git a/src/viem/Account.test.ts b/src/viem/Account.test.ts deleted file mode 100644 index 8e1f7f32..00000000 --- a/src/viem/Account.test.ts +++ /dev/null @@ -1,444 +0,0 @@ -import { Value, WebCryptoP256 } from 'ox' -import { SignatureEnvelope } from 'ox/tempo' -import { describe, expect, test } from 'vitest' -import * as Account from './Account.js' - -const privateKey_secp256k1 = - '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' -const privateKey_p256 = - '0x5c878151adef73f88b1c360d33e9bf9dd1b6e2e0e07bc555fc33cb8cf6bc9b28' - -describe('fromSecp256k1', () => { - test('default', async () => { - const account = Account.fromSecp256k1(privateKey_secp256k1) - expect(account).toMatchInlineSnapshot(` - { - "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "assignKeyAuthorization": [Function], - "keyType": "secp256k1", - "publicKey": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", - "sign": [Function], - "signAuthorization": [Function], - "signKeyAuthorization": [Function], - "signMessage": [Function], - "signTransaction": [Function], - "signTypedData": [Function], - "source": "root", - "storage": { - "getItem": [Function], - "removeItem": [Function], - "setItem": [Function], - }, - "type": "local", - } - `) - - const signature = await account.sign({ - hash: '0xdeadbeef', - }) - expect(signature).toMatchInlineSnapshot( - `"0xfa78c5905fb0b9d6066ef531f962a62bc6ef0d5eb59ecb134056d206f75aaed7780926ff2601a935c2c79707d9e1799948c9f19dcdde1e090e903b19a07923d01c"`, - ) - expect(SignatureEnvelope.deserialize(signature)).toMatchInlineSnapshot(` - { - "signature": { - "r": 113291597329930009559670063131885256927775966057121513567941051428123344285399n, - "s": 54293712598725100598138577281441749550405991478212695085505730636505228583888n, - "yParity": 1, - }, - "type": "secp256k1", - } - `) - }) - - test('behavior: access key', async () => { - const account = Account.fromSecp256k1(privateKey_secp256k1) - const access = Account.fromSecp256k1( - '0x06a952d58c24d287245276dd8b4272d82a921d27d90874a6c27a3bc19ff4bfde', - { - access: account, - }, - ) - - const signature = await access.sign({ - hash: '0xdeadbeef', - }) - expect(signature).toMatchInlineSnapshot( - `"0x03f39Fd6e51aad88F6F4ce6aB8827279cffFb9226627c4025daa5c473942fd6282cfb7c07edb48a1764fb3c228fc094a715300e0e56fcf8a7849bb8bcc2938d8a041fdbce56d2b6c70aadbae6a0b70b4a1e98256161b"`, - ) - expect(SignatureEnvelope.deserialize(signature)).toMatchInlineSnapshot(` - { - "inner": { - "signature": { - "r": 17986519448152736741806679848301503760738507672285374215138617395147700232421n, - "s": 50573419219106101097329274608677894804280434221354410855341207650465321473558n, - "yParity": 0, - }, - "type": "secp256k1", - }, - "type": "keychain", - "userAddress": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - }) -}) - -describe('fromP256', () => { - test('default', async () => { - const account = Account.fromP256(privateKey_p256) - expect(account).toMatchInlineSnapshot(` - { - "address": "0xc3Cf8B814B729A1ad648b49fbBdED3767BCd35fd", - "assignKeyAuthorization": [Function], - "keyType": "p256", - "publicKey": "0x20fe09fa1af47a6b3b4e973040f0588a1c2c96df1ce78b10e50903566ad9b7d87ffe0b281b616196c2ccdb64cd51230d8dc1f1d258ca7e8cb33a63cf8c812240", - "sign": [Function], - "signAuthorization": [Function], - "signKeyAuthorization": [Function], - "signMessage": [Function], - "signTransaction": [Function], - "signTypedData": [Function], - "source": "root", - "storage": { - "getItem": [Function], - "removeItem": [Function], - "setItem": [Function], - }, - "type": "local", - } - `) - - const signature = await account.sign({ - hash: '0xdeadbeef', - }) - expect(signature).toMatchInlineSnapshot( - `"0x01daab749a3dea3f76c52ff0cfc86f0d433ecaf4d20f2ea327042bf5c15bccf847098dc3591fc68bf94d8db6d16cf326808dbf0f44d8e8373e8a7fcaf39b38281020fe09fa1af47a6b3b4e973040f0588a1c2c96df1ce78b10e50903566ad9b7d87ffe0b281b616196c2ccdb64cd51230d8dc1f1d258ca7e8cb33a63cf8c81224000"`, - ) - }) - - test('behavior: access key', async () => { - const account = Account.fromP256(privateKey_p256) - const access = Account.fromP256( - '0x5c878151adef73f88b1c360d33e9bf9dd1b6e2e0e07bc555fc33cb8cf6bc9b28', - { - access: account, - }, - ) - - const signature = await access.sign({ - hash: '0xdeadbeef', - }) - expect(signature).toMatchInlineSnapshot( - `"0x03c3Cf8B814B729A1ad648b49fbBdED3767BCd35fd01daab749a3dea3f76c52ff0cfc86f0d433ecaf4d20f2ea327042bf5c15bccf847098dc3591fc68bf94d8db6d16cf326808dbf0f44d8e8373e8a7fcaf39b38281020fe09fa1af47a6b3b4e973040f0588a1c2c96df1ce78b10e50903566ad9b7d87ffe0b281b616196c2ccdb64cd51230d8dc1f1d258ca7e8cb33a63cf8c81224000"`, - ) - expect(SignatureEnvelope.deserialize(signature)).toMatchInlineSnapshot(` - { - "inner": { - "prehash": false, - "publicKey": { - "prefix": 4, - "x": 14922859167660714031319135249406228569331107293314503672038378501577989797848n, - "y": 57892587925019714505251703757706314187537979987563648366993255393643804566080n, - }, - "signature": { - "r": 98907136600157604623356371387339224256063842362088951992859252568183251204167n, - "s": 4321289316702385668777418513388640777474210589895706234285069930616319387664n, - }, - "type": "p256", - }, - "type": "keychain", - "userAddress": "0xc3Cf8B814B729A1ad648b49fbBdED3767BCd35fd", - } - `) - }) -}) - -describe('fromHeadlessWebAuthn', () => { - test('default', async () => { - const account = Account.fromHeadlessWebAuthn(privateKey_p256, { - rpId: 'localhost', - origin: 'http://localhost', - }) - expect(account).toMatchInlineSnapshot(` - { - "address": "0xc3Cf8B814B729A1ad648b49fbBdED3767BCd35fd", - "assignKeyAuthorization": [Function], - "keyType": "webAuthn", - "publicKey": "0x20fe09fa1af47a6b3b4e973040f0588a1c2c96df1ce78b10e50903566ad9b7d87ffe0b281b616196c2ccdb64cd51230d8dc1f1d258ca7e8cb33a63cf8c812240", - "sign": [Function], - "signAuthorization": [Function], - "signKeyAuthorization": [Function], - "signMessage": [Function], - "signTransaction": [Function], - "signTypedData": [Function], - "source": "root", - "storage": { - "getItem": [Function], - "removeItem": [Function], - "setItem": [Function], - }, - "type": "local", - } - `) - - const signature = await account.sign({ - hash: '0xdeadbeef', - }) - expect(signature).toMatchInlineSnapshot( - `"0x0249960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d976305000000007b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a223371322d3777222c226f726967696e223a22687474703a2f2f6c6f63616c686f7374222c2263726f73734f726967696e223a66616c73657d1b3346991a9ad1498e401dc0448e93d1bde113778d442f5bcafc44925cf3121961e9b1c21b054e54fe6c2eec0cd310c8535b7e7dd1f7dd7bf749e6d78154b48120fe09fa1af47a6b3b4e973040f0588a1c2c96df1ce78b10e50903566ad9b7d87ffe0b281b616196c2ccdb64cd51230d8dc1f1d258ca7e8cb33a63cf8c812240"`, - ) - }) - - test('behavior: access key', async () => { - const account = Account.fromHeadlessWebAuthn(privateKey_p256, { - rpId: 'localhost', - origin: 'http://localhost', - }) - const access = Account.fromHeadlessWebAuthn(privateKey_p256, { - access: account, - rpId: 'localhost', - origin: 'http://localhost', - }) - - const signature = await access.sign({ - hash: '0xdeadbeef', - }) - expect(signature).toMatchInlineSnapshot( - `"0x03c3Cf8B814B729A1ad648b49fbBdED3767BCd35fd0249960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d976305000000007b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a223371322d3777222c226f726967696e223a22687474703a2f2f6c6f63616c686f7374222c2263726f73734f726967696e223a66616c73657d1b3346991a9ad1498e401dc0448e93d1bde113778d442f5bcafc44925cf3121961e9b1c21b054e54fe6c2eec0cd310c8535b7e7dd1f7dd7bf749e6d78154b48120fe09fa1af47a6b3b4e973040f0588a1c2c96df1ce78b10e50903566ad9b7d87ffe0b281b616196c2ccdb64cd51230d8dc1f1d258ca7e8cb33a63cf8c812240"`, - ) - expect(SignatureEnvelope.deserialize(signature)).toMatchInlineSnapshot(` - { - "inner": { - "metadata": { - "authenticatorData": "0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000", - "clientDataJSON": "{"type":"webauthn.get","challenge":"3q2-7w","origin":"http://localhost","crossOrigin":false}", - }, - "publicKey": { - "prefix": 4, - "x": 14922859167660714031319135249406228569331107293314503672038378501577989797848n, - "y": 57892587925019714505251703757706314187537979987563648366993255393643804566080n, - }, - "signature": { - "r": 12303043361969813321008510595799352303777626167191077212436720864556362175001n, - "s": 44287248520848853208449965274039658906134850867725872574460252467151437608065n, - }, - "type": "webAuthn", - }, - "type": "keychain", - "userAddress": "0xc3Cf8B814B729A1ad648b49fbBdED3767BCd35fd", - } - `) - }) -}) - -describe('fromWebCryptoP256', () => { - test('default', async () => { - const keyPair = await WebCryptoP256.createKeyPair() - const account = Account.fromWebCryptoP256(keyPair) - expect(account.keyType).toBe('p256') - }) -}) - -describe('signKeyAuthorization', () => { - test('default', async () => { - const account = Account.fromSecp256k1(privateKey_secp256k1) - const key = Account.fromSecp256k1(privateKey_secp256k1, { - access: account, - }) - - const authorization = await account.signKeyAuthorization(key) - - expect(authorization).toMatchInlineSnapshot(` - { - "address": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "expiry": undefined, - "limits": undefined, - "signature": { - "signature": { - "r": 79205852917725370379355270588870592116219723320468023492479334723587833964208n, - "s": 4843127791679253574310716587415423223041264865988930666086461408483250881493n, - "yParity": 1, - }, - "type": "secp256k1", - }, - "type": "secp256k1", - } - `) - }) - - test('secp256k1', async () => { - const account = Account.fromSecp256k1(privateKey_secp256k1) - const key = Account.fromSecp256k1(privateKey_secp256k1, { - access: account, - }) - - const authorization = await account.signKeyAuthorization(key, { - expiry: 1234567890, - limits: [ - { - token: '0x20c0000000000000000000000000000000000001', - limit: Value.from('10', 6), - }, - ], - }) - expect(authorization).toMatchInlineSnapshot(` - { - "address": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "expiry": 1234567890, - "limits": [ - { - "limit": 10000000n, - "token": "0x20c0000000000000000000000000000000000001", - }, - ], - "signature": { - "signature": { - "r": 48603032183460068649726257603541287031240449157747147951793434940348798421977n, - "s": 52252948283033674801195452183159160801795536276956563866652050470169279213377n, - "yParity": 1, - }, - "type": "secp256k1", - }, - "type": "secp256k1", - } - `) - }) - - test('p256', async () => { - const account = Account.fromP256(privateKey_p256) - const key = Account.fromSecp256k1(privateKey_p256, { - access: account, - }) - - const authorization = await account.signKeyAuthorization(key, { - expiry: 1234567890, - limits: [ - { - token: '0x20c0000000000000000000000000000000000001', - limit: Value.from('10', 6), - }, - ], - }) - expect(authorization).toMatchInlineSnapshot(` - { - "address": "0x7b9f73245dee5855ef858f5c00eea6205f9bb4d2", - "expiry": 1234567890, - "limits": [ - { - "limit": 10000000n, - "token": "0x20c0000000000000000000000000000000000001", - }, - ], - "signature": { - "prehash": false, - "publicKey": { - "prefix": 4, - "x": 14922859167660714031319135249406228569331107293314503672038378501577989797848n, - "y": 57892587925019714505251703757706314187537979987563648366993255393643804566080n, - }, - "signature": { - "r": 61783347383434217927888325272237644430195567463134160594444735116547420206984n, - "s": 11737632122119624918549121055165681708107124199303685870565323985056705147576n, - }, - "type": "p256", - }, - "type": "secp256k1", - } - `) - }) - - test('webAuthn', async () => { - const account = Account.fromHeadlessWebAuthn(privateKey_p256, { - rpId: 'localhost', - origin: 'http://localhost', - }) - const key = Account.fromSecp256k1(privateKey_secp256k1, { - access: account, - }) - - const authorization = await account.signKeyAuthorization(key, { - expiry: 1234567890, - limits: [ - { - token: '0x20c0000000000000000000000000000000000001', - limit: Value.from('10', 6), - }, - ], - }) - expect(authorization).toMatchInlineSnapshot(` - { - "address": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "expiry": 1234567890, - "limits": [ - { - "limit": 10000000n, - "token": "0x20c0000000000000000000000000000000000001", - }, - ], - "signature": { - "metadata": { - "authenticatorData": "0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000", - "clientDataJSON": "{"type":"webauthn.get","challenge":"lGAMxkLdccXnNTMWbfQ1rYi8HBqAdMPo1CDv0cJ2IsE","origin":"http://localhost","crossOrigin":false}", - }, - "publicKey": { - "prefix": 4, - "x": 14922859167660714031319135249406228569331107293314503672038378501577989797848n, - "y": 57892587925019714505251703757706314187537979987563648366993255393643804566080n, - }, - "signature": { - "r": 78216200649325922174765550266136727201161525335688064274452437990389629688142n, - "s": 45615041673857220498429503388722739621903077428603741554126666038202271956449n, - }, - "type": "webAuthn", - }, - "type": "secp256k1", - } - `) - }) - - test('multiple limits', async () => { - const account = Account.fromSecp256k1(privateKey_secp256k1) - const key = Account.fromSecp256k1(privateKey_secp256k1, { - access: account, - }) - - const authorization = await account.signKeyAuthorization(key, { - expiry: 1234567890, - limits: [ - { - token: '0x20c0000000000000000000000000000000000001', - limit: Value.from('10', 6), - }, - { - token: '0x20c0000000000000000000000000000000000002', - limit: Value.from('20', 6), - }, - ], - }) - expect(authorization).toMatchInlineSnapshot(` - { - "address": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "expiry": 1234567890, - "limits": [ - { - "limit": 10000000n, - "token": "0x20c0000000000000000000000000000000000001", - }, - { - "limit": 20000000n, - "token": "0x20c0000000000000000000000000000000000002", - }, - ], - "signature": { - "signature": { - "r": 103446563773805832555738463837136311499830712555215862064308154410957015968940n, - "s": 19247215858016211284757060583528935834485291841858715669623661689922072500812n, - "yParity": 0, - }, - "type": "secp256k1", - }, - "type": "secp256k1", - } - `) - }) -}) diff --git a/src/viem/Account.ts b/src/viem/Account.ts deleted file mode 100644 index 6c40fac5..00000000 --- a/src/viem/Account.ts +++ /dev/null @@ -1,601 +0,0 @@ -import * as Address from 'ox/Address' -import * as Hex from 'ox/Hex' -import * as P256 from 'ox/P256' -import * as PublicKey from 'ox/PublicKey' -import * as Secp256k1 from 'ox/Secp256k1' -import * as Signature from 'ox/Signature' -import { KeyAuthorization, SignatureEnvelope } from 'ox/tempo' -import * as WebAuthnP256 from 'ox/WebAuthnP256' -import * as WebCryptoP256 from 'ox/WebCryptoP256' -import type { LocalAccount, RequiredBy, Account as viem_Account } from 'viem' -import { - hashAuthorization, - hashMessage, - hashTypedData, - keccak256, - parseAccount, -} from 'viem/utils' -import type { OneOf } from '../internal/types.js' -import * as Storage from './Storage.js' -import * as Transaction from './Transaction.js' - -type StorageSchema = { - pendingKeyAuthorization?: KeyAuthorization.Signed | undefined -} - -export type Account_base = RequiredBy< - LocalAccount, - 'sign' | 'signAuthorization' -> & { - /** Key type. */ - keyType: SignatureEnvelope.Type - /** Account storage. */ - storage: Storage.Storage -} - -export type RootAccount = Account_base<'root'> & { - /** Assign key authorization to the next transaction. */ - assignKeyAuthorization: ( - keyAuthorization: KeyAuthorization.Signed, - ) => Promise - /** Sign key authorization. */ - signKeyAuthorization: ( - key: Pick, - parameters?: Pick, - ) => Promise -} - -export type AccessKeyAccount = Account_base<'accessKey'> & { - /** Access key ID. */ - accessKeyAddress: Address.Address -} - -export type Account = OneOf - -/** - * Instantiates an Account from a headless WebAuthn credential (P256 private key). - * - * @example - * ```ts - * import { Account } from 'tempo.ts/viem' - * - * const account = Account.fromHeadlessWebAuthn('0x...') - * ``` - * - * @param privateKey P256 private key. - * @returns Account. - */ -export function fromHeadlessWebAuthn< - const options extends fromHeadlessWebAuthn.Options, ->( - privateKey: Hex.Hex, - options: options | fromHeadlessWebAuthn.Options, -): fromHeadlessWebAuthn.ReturnValue { - const { access, rpId, origin, storage } = options - - const publicKey = P256.getPublicKey({ privateKey }) - - return from({ - access, - keyType: 'webAuthn', - publicKey, - async sign({ hash }) { - const { metadata, payload } = WebAuthnP256.getSignPayload({ - ...options, - challenge: hash, - rpId, - origin, - }) - const signature = P256.sign({ - payload, - privateKey, - hash: true, - }) - return SignatureEnvelope.serialize({ - metadata, - signature, - publicKey, - type: 'webAuthn', - }) - }, - storage, - }) as never -} - -export declare namespace fromHeadlessWebAuthn { - export type Options = Omit< - WebAuthnP256.getSignPayload.Options, - 'challenge' | 'rpId' | 'origin' - > & - Pick & { - rpId: string - origin: string - } - - export type ReturnValue = - from.ReturnValue -} - -/** - * Instantiates an Account from a P256 private key. - * - * @example - * ```ts - * import { Account } from 'tempo.ts/viem' - * - * const account = Account.fromP256('0x...') - * ``` - * - * @param privateKey P256 private key. - * @returns Account. - */ -export function fromP256( - privateKey: Hex.Hex, - options: options | fromP256.Options = {}, -): fromP256.ReturnValue { - const { access, storage } = options - const publicKey = P256.getPublicKey({ privateKey }) - - return from({ - access, - keyType: 'p256', - publicKey, - async sign({ hash }) { - const signature = P256.sign({ payload: hash, privateKey }) - return SignatureEnvelope.serialize({ - signature, - publicKey, - type: 'p256', - }) - }, - storage, - }) as never -} - -export declare namespace fromP256 { - export type Options = Pick - - export type ReturnValue = - from.ReturnValue -} - -/** - * Instantiates an Account from a Secp256k1 private key. - * - * @example - * ```ts - * import { Account } from 'tempo.ts/viem' - * - * const account = Account.fromSecp256k1('0x...') - * ``` - * - * @param privateKey Secp256k1 private key. - * @returns Account. - */ -// TODO: this function will be redundant when Viem migrates to Ox. -export function fromSecp256k1( - privateKey: Hex.Hex, - options: options | fromSecp256k1.Options = {}, -): fromSecp256k1.ReturnValue { - const { access, storage } = options - const publicKey = Secp256k1.getPublicKey({ privateKey }) - - return from({ - access, - keyType: 'secp256k1', - publicKey, - async sign(parameters) { - const { hash } = parameters - const signature = Secp256k1.sign({ payload: hash, privateKey }) - return Signature.toHex(signature) - }, - storage, - }) as never -} - -export declare namespace fromSecp256k1 { - export type Options = Pick - - export type ReturnValue = - from.ReturnValue -} - -/** - * Instantiates an Account from a WebAuthn credential. - * - * @example - * - * ### Create Passkey + Instantiate Account - * - * Create a credential with `WebAuthnP256.createCredential` and then instantiate - * a Viem Account with `Account.fromWebAuthnP256`. - * - * It is highly recommended to store the credential's public key in an external store - * for future use (ie. for future calls to `WebAuthnP256.getCredential`). - * - * ```ts - * import { Account, WebAuthnP256 } from 'tempo.ts/viem' - * import { publicKeyStore } from './store' - * - * // 1. Create credential - * const credential = await WebAuthnP256.createCredential({ name: 'Example' }) - * - * // 2. Instantiate account - * const account = Account.fromWebAuthnP256(credential) - * - * // 3. Store public key - * await publicKeyStore.set(credential.id, credential.publicKey) - * - * ``` - * - * @example - * - * ### Get Credential + Instantiate Account - * - * Gets a credential from `WebAuthnP256.getCredential` and then instantiates - * an account with `Account.fromWebAuthnP256`. - * - * The `getPublicKey` function is required to fetch the public key paired with the credential - * from an external store. The public key is required to derive the account's address. - * - * ```ts - * import { Account, WebAuthnP256 } from 'tempo.ts/viem' - * import { publicKeyStore } from './store' - * - * // 1. Get credential - * const credential = await WebAuthnP256.getCredential({ - * async getPublicKey(credential) { - * // 2. Get public key from external store. - * return await publicKeyStore.get(credential.id) - * } - * }) - * - * // 3. Instantiate account - * const account = Account.fromWebAuthnP256(credential) - * ``` - * - * @param credential WebAuthnP256 credential. - * @returns Account. - */ -export function fromWebAuthnP256( - credential: fromWebAuthnP256.Credential, - options: fromWebAuthnP256.Options = {}, -): fromWebAuthnP256.ReturnValue { - const { id } = credential - const { storage } = options - const publicKey = PublicKey.fromHex(credential.publicKey) - return from({ - keyType: 'webAuthn', - publicKey, - async sign({ hash }) { - const { metadata, signature } = await WebAuthnP256.sign({ - ...options, - challenge: hash, - credentialId: id, - }) - return SignatureEnvelope.serialize({ - publicKey, - metadata, - signature, - type: 'webAuthn', - }) - }, - storage, - }) -} - -export declare namespace fromWebAuthnP256 { - export type Credential = { - id: WebAuthnP256.P256Credential['id'] - publicKey: Hex.Hex - } - - export type Options = { - getFn?: WebAuthnP256.sign.Options['getFn'] | undefined - rpId?: WebAuthnP256.sign.Options['rpId'] | undefined - storage?: from.Parameters['storage'] | undefined - } - - export type ReturnValue = from.ReturnValue -} - -/** - * Instantiates an Account from a P256 private key. - * - * @example - * ```ts - * import { Account } from 'tempo.ts/viem' - * import { WebCryptoP256 } from 'ox' - * - * const keyPair = await WebCryptoP256.createKeyPair() - * - * const account = Account.fromWebCryptoP256(keyPair) - * ``` - * - * @param keyPair WebCryptoP256 key pair. - * @returns Account. - */ -export function fromWebCryptoP256< - const options extends fromWebCryptoP256.Options, ->( - keyPair: Awaited>, - options: options | fromWebCryptoP256.Options = {}, -): fromWebCryptoP256.ReturnValue { - const { access, storage } = options - const { publicKey, privateKey } = keyPair - - return from({ - access, - keyType: 'p256', - publicKey, - async sign({ hash }) { - const signature = await WebCryptoP256.sign({ payload: hash, privateKey }) - return SignatureEnvelope.serialize({ - signature, - prehash: true, - publicKey, - type: 'p256', - }) - }, - storage, - }) as never -} - -export declare namespace fromWebCryptoP256 { - export type Options = Pick - - export type ReturnValue = - from.ReturnValue -} - -export async function signKeyAuthorization( - account: LocalAccount, - parameters: signKeyAuthorization.Parameters, -): Promise { - const { key, expiry, limits } = parameters - const { accessKeyAddress, keyType: type } = key - - const signature = await account.sign!({ - hash: KeyAuthorization.getSignPayload({ - address: accessKeyAddress, - expiry, - limits, - type, - }), - }) - return KeyAuthorization.from({ - address: accessKeyAddress, - expiry, - limits, - signature: SignatureEnvelope.from(signature), - type, - }) -} - -export declare namespace signKeyAuthorization { - type Parameters = Pick< - KeyAuthorization.KeyAuthorization, - 'expiry' | 'limits' - > & { - key: Pick - } - - type ReturnValue = KeyAuthorization.Signed -} - -/** @internal */ -// biome-ignore lint/correctness/noUnusedVariables: _ -function fromBase(parameters: fromBase.Parameters): Account_base { - const { - keyType = 'secp256k1', - parentAddress, - source = 'privateKey', - } = parameters - - const address = parentAddress ?? Address.fromPublicKey(parameters.publicKey) - const publicKey = PublicKey.toHex(parameters.publicKey, { - includePrefix: false, - }) - - const storage = Storage.from( - parameters.storage ?? Storage.memory(), - { key: `tempo.ts:${address.toLowerCase()}` }, - ) - - async function sign({ hash }: { hash: Hex.Hex }) { - const signature = await parameters.sign({ hash }) - if (parentAddress) - return SignatureEnvelope.serialize( - SignatureEnvelope.from({ - userAddress: parentAddress, - inner: SignatureEnvelope.from(signature), - type: 'keychain', - }), - ) - - return signature - } - - return { - address: Address.checksum(address), - keyType, - sign, - async signAuthorization(parameters) { - const { chainId, nonce } = parameters - const address = parameters.contractAddress ?? parameters.address - const signature = await sign({ - hash: hashAuthorization({ address, chainId, nonce }), - }) - const envelope = SignatureEnvelope.from(signature) - if (envelope.type !== 'secp256k1') - throw new Error( - 'Unsupported signature type. Expected `secp256k1` but got `' + - envelope.type + - '`.', - ) - const { r, s, yParity } = envelope.signature - return { - address, - chainId, - nonce, - r: Hex.fromNumber(r, { size: 32 }), - s: Hex.fromNumber(s, { size: 32 }), - yParity, - } - }, - async signMessage(parameters) { - const { message } = parameters - const signature = await sign({ hash: hashMessage(message) }) - const envelope = SignatureEnvelope.from(signature) - return SignatureEnvelope.serialize(envelope) - }, - async signTransaction(transaction, options) { - const { serializer = Transaction.serialize } = options ?? {} - - const keyAuthorization = - (await storage?.getItem('pendingKeyAuthorization')) ?? undefined - if (keyAuthorization && !(transaction as any).keyAuthorization) { - ;(transaction as any).keyAuthorization = keyAuthorization - await storage.removeItem('pendingKeyAuthorization') - } - - const signature = await sign({ - hash: keccak256(await serializer(transaction)), - }) - const envelope = SignatureEnvelope.from(signature) - return await serializer(transaction, envelope as never) - }, - async signTypedData(typedData) { - const signature = await sign({ hash: hashTypedData(typedData) }) - const envelope = SignatureEnvelope.from(signature) - return SignatureEnvelope.serialize(envelope) - }, - publicKey, - source, - storage, - type: 'local', - } -} - -declare namespace fromBase { - export type Parameters = { - /** Parent address. */ - parentAddress?: Address.Address | undefined - /** Public key. */ - publicKey: PublicKey.PublicKey - /** Key type. */ - keyType?: SignatureEnvelope.Type | undefined - /** Sign function. */ - sign: NonNullable - /** Source. */ - source?: string | undefined - /** - * Account storage. - * Used for access key management, and pending key authorizations. - * @default `Storage.memory()` - */ - storage?: Storage.Storage | undefined - } - - export type ReturnValue = Account_base -} - -/** @internal */ -// biome-ignore lint/correctness/noUnusedVariables: _ -function fromRoot(parameters: fromRoot.Parameters): RootAccount { - const account = fromBase(parameters) - return { - ...account, - source: 'root', - async assignKeyAuthorization(keyAuthorization) { - account.storage.setItem('pendingKeyAuthorization', keyAuthorization) - }, - async signKeyAuthorization(key, parameters = {}) { - const { expiry, limits } = parameters - const { accessKeyAddress, keyType: type } = key - - const signature = await account.sign({ - hash: KeyAuthorization.getSignPayload({ - address: accessKeyAddress, - expiry, - limits, - type, - }), - }) - const keyAuthorization = KeyAuthorization.from({ - address: accessKeyAddress, - expiry, - limits, - signature: SignatureEnvelope.from(signature), - type, - }) - return keyAuthorization - }, - } -} - -declare namespace fromRoot { - export type Parameters = fromBase.Parameters - - export type ReturnValue = RootAccount -} - -// biome-ignore lint/correctness/noUnusedVariables: _ -function fromAccessKey(parameters: fromAccessKey.Parameters): AccessKeyAccount { - const { access } = parameters - const { address: parentAddress } = parseAccount(access) - const account = fromBase({ ...parameters, parentAddress }) - return { - ...account, - accessKeyAddress: Address.fromPublicKey(parameters.publicKey), - source: 'accessKey', - } -} - -declare namespace fromAccessKey { - export type Parameters = fromBase.Parameters & { - /** - * Parent account to access. - * If defined, this account will act as an "access key", and use - * the parent account's address as the keychain address. - */ - access: viem_Account | Address.Address - } - - export type ReturnValue = AccessKeyAccount -} - -// biome-ignore lint/correctness/noUnusedVariables: _ -function from( - parameters: parameters | from.Parameters, -): from.ReturnValue { - const { access } = parameters - if (access) return fromAccessKey(parameters) as never - return fromRoot(parameters) as never -} - -declare namespace from { - export type Parameters = OneOf - - export type ReturnValue< - parameters extends { - access?: fromAccessKey.Parameters['access'] | undefined - } = { - access?: fromAccessKey.Parameters['access'] | undefined - }, - > = parameters extends { - access: fromAccessKey.Parameters['access'] - } - ? AccessKeyAccount - : RootAccount -} - -// Export types required for inference. -export { - /** @deprecated */ - KeyAuthorization as z_KeyAuthorization, - /** @deprecated */ - SignatureEnvelope as z_SignatureEnvelope, - /** @deprecated */ - TxEnvelopeTempo as z_TxEnvelopeTempo, -} from 'ox/tempo' diff --git a/src/viem/Actions/account.test.ts b/src/viem/Actions/account.test.ts deleted file mode 100644 index b2b48987..00000000 --- a/src/viem/Actions/account.test.ts +++ /dev/null @@ -1,414 +0,0 @@ -import { Hex, P256, Secp256k1, WebCryptoP256 } from 'ox' -import { verifyMessage, verifyTypedData } from 'viem/actions' -import { describe, expect, test } from 'vitest' -import { client as baseClient } from '../../../test/viem/config.js' -import * as Account from '../Account.js' -import { decorator as tempoActions } from '../Decorator.js' -import * as actions from './account.js' - -const client = baseClient.extend(tempoActions()) - -describe('verifyHash', () => { - test('secp256k1: default signature', async () => { - const privateKey = Secp256k1.randomPrivateKey() - const account = Account.fromSecp256k1(privateKey) - - const hash = Hex.random(32) - const signature = await account.sign({ hash }) - - const valid = await actions.verifyHash(client, { - address: account.address, - hash, - signature, - }) - - expect(valid).toBe(true) - }) - - test('secp256k1: without address (recovers from signature)', async () => { - const privateKey = Secp256k1.randomPrivateKey() - const account = Account.fromSecp256k1(privateKey) - - const hash = Hex.random(32) - const signature = await account.sign({ hash }) - - const valid = await actions.verifyHash(client, { - hash, - signature, - }) - - expect(valid).toBe(true) - }) - - test('secp256k1: invalid signature returns false', async () => { - const privateKey = Secp256k1.randomPrivateKey() - const account = Account.fromSecp256k1(privateKey) - - const hash = Hex.random(32) - const wrongHash = Hex.random(32) - const signature = await account.sign({ hash }) - - const valid = await actions.verifyHash(client, { - address: account.address, - hash: wrongHash, - signature, - }) - - expect(valid).toBe(false) - }) - - test('p256: default signature', async () => { - const privateKey = P256.randomPrivateKey() - const account = Account.fromP256(privateKey) - - const hash = Hex.random(32) - const signature = await account.sign({ hash }) - - const valid = await actions.verifyHash(client, { - address: account.address, - hash, - signature, - }) - - expect(valid).toBe(true) - }) - - test('p256: invalid signature returns false', async () => { - const privateKey = P256.randomPrivateKey() - const account = Account.fromP256(privateKey) - - const hash = Hex.random(32) - const wrongHash = Hex.random(32) - const signature = await account.sign({ hash }) - - const valid = await actions.verifyHash(client, { - address: account.address, - hash: wrongHash, - signature, - }) - - expect(valid).toBe(false) - }) - - test('webCrypto p256: default signature', async () => { - const keyPair = await WebCryptoP256.createKeyPair() - const account = Account.fromWebCryptoP256(keyPair) - - const hash = Hex.random(32) - const signature = await account.sign({ hash }) - - const valid = await actions.verifyHash(client, { - address: account.address, - hash, - signature, - }) - - expect(valid).toBe(true) - }) - - test('webCrypto p256: invalid signature returns false', async () => { - const keyPair = await WebCryptoP256.createKeyPair() - const account = Account.fromWebCryptoP256(keyPair) - - const hash = Hex.random(32) - const wrongHash = Hex.random(32) - const signature = await account.sign({ hash }) - - const valid = await actions.verifyHash(client, { - address: account.address, - hash: wrongHash, - signature, - }) - - expect(valid).toBe(false) - }) - - test('headless webAuthn: default signature', async () => { - const privateKey = P256.randomPrivateKey() - const account = Account.fromHeadlessWebAuthn(privateKey, { - rpId: 'example.com', - origin: 'https://example.com', - }) - - const hash = Hex.random(32) - const signature = await account.sign({ hash }) - - const valid = await actions.verifyHash(client, { - address: account.address, - hash, - signature, - }) - - expect(valid).toBe(true) - }) - - test('headless webAuthn: invalid signature returns false', async () => { - const privateKey = P256.randomPrivateKey() - const account = Account.fromHeadlessWebAuthn(privateKey, { - rpId: 'example.com', - origin: 'https://example.com', - }) - - const hash = Hex.random(32) - const wrongHash = Hex.random(32) - const signature = await account.sign({ hash }) - - const valid = await actions.verifyHash(client, { - address: account.address, - hash: wrongHash, - signature, - }) - - expect(valid).toBe(false) - }) - - test('behavior: signature from wrong account returns false', async () => { - const privateKey1 = Secp256k1.randomPrivateKey() - const account1 = Account.fromSecp256k1(privateKey1) - - const privateKey2 = Secp256k1.randomPrivateKey() - const account2 = Account.fromSecp256k1(privateKey2) - - const hash = Hex.random(32) - const signature = await account1.sign({ hash }) - - // Try to verify with wrong address - const valid = await actions.verifyHash(client, { - address: account2.address, - hash, - signature, - }) - - expect(valid).toBe(false) - }) - - test('as inherited: verifyMessage with secp256k1', async () => { - const privateKey = Secp256k1.randomPrivateKey() - const account = Account.fromSecp256k1(privateKey) - - const message = 'Hello, World!' - const signature = await account.signMessage({ message }) - - const valid = await verifyMessage(client, { - address: account.address, - message, - signature, - }) - - expect(valid).toBe(true) - }) - - test('as inherited: verifyMessage with p256', async () => { - const privateKey = P256.randomPrivateKey() - const account = Account.fromP256(privateKey) - - const message = 'Hello, P256!' - const signature = await account.signMessage({ message }) - - const valid = await verifyMessage(client, { - address: account.address, - message, - signature, - }) - - expect(valid).toBe(true) - }) - - test('as inherited: verifyMessage with webCrypto p256', async () => { - const keyPair = await WebCryptoP256.createKeyPair() - const account = Account.fromWebCryptoP256(keyPair) - - const message = 'Hello, WebCrypto!' - const signature = await account.signMessage({ message }) - - const valid = await verifyMessage(client, { - address: account.address, - message, - signature, - }) - - expect(valid).toBe(true) - }) - - test('as inherited: verifyMessage with headless webAuthn', async () => { - const privateKey = P256.randomPrivateKey() - const account = Account.fromHeadlessWebAuthn(privateKey, { - rpId: 'example.com', - origin: 'https://example.com', - }) - - const message = 'Hello, WebAuthn!' - const signature = await account.signMessage({ message }) - - const valid = await verifyMessage(client, { - address: account.address, - message, - signature, - }) - - expect(valid).toBe(true) - }) - - test('as inherited: verifyTypedData with secp256k1', async () => { - const privateKey = Secp256k1.randomPrivateKey() - const account = Account.fromSecp256k1(privateKey) - - const domain = { - name: 'Test App', - version: '1', - chainId: 1, - } - - const types = { - Person: [ - { name: 'name', type: 'string' }, - { name: 'wallet', type: 'address' }, - ], - } - - const message = { - name: 'Alice', - wallet: '0x0000000000000000000000000000000000000000', - } - - const signature = await account.signTypedData({ - domain, - types, - primaryType: 'Person', - message, - }) - - const valid = await verifyTypedData(client, { - address: account.address, - domain, - types, - primaryType: 'Person', - message, - signature, - }) - - expect(valid).toBe(true) - }) - - test('as inherited: verifyTypedData with p256', async () => { - const privateKey = P256.randomPrivateKey() - const account = Account.fromP256(privateKey) - - const domain = { - name: 'P256 App', - version: '1', - chainId: 1, - } - - const types = { - Message: [{ name: 'content', type: 'string' }], - } - - const message = { - content: 'Hello from P256!', - } - - const signature = await account.signTypedData({ - domain, - types, - primaryType: 'Message', - message, - }) - - const valid = await verifyTypedData(client, { - address: account.address, - domain, - types, - primaryType: 'Message', - message, - signature, - }) - - expect(valid).toBe(true) - }) - - test('as inherited: verifyTypedData with webCrypto p256', async () => { - const keyPair = await WebCryptoP256.createKeyPair() - const account = Account.fromWebCryptoP256(keyPair) - - const domain = { - name: 'WebCrypto App', - version: '1', - chainId: 1, - } - - const types = { - Data: [ - { name: 'value', type: 'uint256' }, - { name: 'label', type: 'string' }, - ], - } - - const message = { - value: 42n, - label: 'test', - } - - const signature = await account.signTypedData({ - domain, - types, - primaryType: 'Data', - message, - }) - - const valid = await verifyTypedData(client, { - address: account.address, - domain, - types, - primaryType: 'Data', - message, - signature, - }) - - expect(valid).toBe(true) - }) - - test('as inherited: verifyTypedData with headless webAuthn', async () => { - const privateKey = P256.randomPrivateKey() - const account = Account.fromHeadlessWebAuthn(privateKey, { - rpId: 'example.com', - origin: 'https://example.com', - }) - - const domain = { - name: 'WebAuthn App', - version: '1', - chainId: 1, - } - - const types = { - Auth: [ - { name: 'user', type: 'address' }, - { name: 'action', type: 'string' }, - ], - } - - const message = { - user: account.address, - action: 'login', - } - - const signature = await account.signTypedData({ - domain, - types, - primaryType: 'Auth', - message, - }) - - const valid = await verifyTypedData(client, { - address: account.address, - domain, - types, - primaryType: 'Auth', - message, - signature, - }) - - expect(valid).toBe(true) - }) -}) diff --git a/src/viem/Actions/account.ts b/src/viem/Actions/account.ts deleted file mode 100644 index 5c5c2681..00000000 --- a/src/viem/Actions/account.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { Secp256k1 } from 'ox' -import * as Hex from 'ox/Hex' -import * as P256 from 'ox/P256' -import { SignatureEnvelope } from 'ox/tempo' -import * as WebAuthnP256 from 'ox/WebAuthnP256' -import type { Chain, Client, Transport } from 'viem' -import type { VerifyHashParameters, VerifyHashReturnType } from 'viem/actions' -import { verifyHash as viem_verifyHash } from 'viem/actions' -import { getAction } from 'viem/utils' -import type { PartialBy } from '../../internal/types.js' - -/** - * Verifies that a signature is valid for a given hash and address. - * Supports multiple signature types: Secp256k1, P256, WebCrypto P256, and WebAuthn P256. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions, Account, P256 } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const privateKey = P256.randomPrivateKey() - * const account = Account.fromP256(privateKey) - * - * const hash = '0x...' - * const signature = await account.sign({ hash }) - * - * const valid = await Actions.verifyHash(client, { - * hash, - * signature, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns Whether the signature is valid. - */ -export async function verifyHash( - client: Client, - parameters: verifyHash.Parameters, -): Promise { - const { hash } = parameters - - const signature = (() => { - const signature = parameters.signature - if (Hex.validate(signature)) return signature - if (typeof signature === 'object' && 'r' in signature && 's' in signature) - return SignatureEnvelope.serialize({ - type: 'secp256k1', - signature: { - r: BigInt(signature.r), - s: BigInt(signature.s), - yParity: signature.yParity!, - }, - }) - return Hex.fromBytes(signature) - })() - - const [envelope, userAddress] = (() => { - const envelope = SignatureEnvelope.from(signature) - if (envelope.type === 'keychain') - return [envelope.inner, envelope.userAddress] - return [envelope, undefined] - })() - - if (envelope.type === 'p256') - return P256.verify({ - payload: hash, - publicKey: envelope.publicKey, - signature: envelope.signature, - hash: envelope.prehash, - }) - if (envelope.type === 'webAuthn') - return WebAuthnP256.verify({ - challenge: hash, - metadata: envelope.metadata, - publicKey: envelope.publicKey, - signature: envelope.signature, - }) - if (envelope.type === 'keychain') throw new Error('not supported') - - const address = - parameters.address ?? - userAddress ?? - Secp256k1.recoverAddress({ - payload: hash, - signature: envelope.signature, - }) - - return await getAction( - client, - viem_verifyHash, - 'verifyHash', - )({ ...parameters, address } as never) -} - -export declare namespace verifyHash { - export type Parameters = PartialBy - - export type ReturnValue = VerifyHashReturnType -} diff --git a/src/viem/Actions/amm.test.ts b/src/viem/Actions/amm.test.ts deleted file mode 100644 index 96ba74c2..00000000 --- a/src/viem/Actions/amm.test.ts +++ /dev/null @@ -1,381 +0,0 @@ -import { setTimeout } from 'node:timers/promises' -import { Abis, Actions } from 'tempo.ts/viem' -import { parseUnits } from 'viem' -import { writeContractSync } from 'viem/actions' -import { describe, expect, test } from 'vitest' -import { - accounts, - clientWithAccount, - setupPoolWithLiquidity, -} from '../../../test/viem/config.js' - -const account = accounts[0] -const account2 = accounts[1] - -describe('getPool', () => { - test('default', async () => { - const pool = await Actions.amm.getPool(clientWithAccount, { - userToken: 1n, - validatorToken: '0x20c0000000000000000000000000000000000001', - }) - expect(pool).toMatchInlineSnapshot(` - { - "reserveUserToken": 0n, - "reserveValidatorToken": 0n, - "totalSupply": 0n, - } - `) - }) -}) - -describe('getLiquidityBalance', () => { - test('default', async () => { - const balance = await Actions.amm.getLiquidityBalance(clientWithAccount, { - address: account.address, - userToken: 1n, - validatorToken: '0x20c0000000000000000000000000000000000001', - }) - expect(typeof balance).toBe('bigint') - }) -}) - -describe('mint', () => { - test('default', async () => { - // Create a new token for testing - const { token } = await Actions.token.createSync(clientWithAccount, { - name: 'Test Token 2', - symbol: 'TEST2', - currency: 'USD', - }) - - // Grant issuer role to mint tokens - await Actions.token.grantRolesSync(clientWithAccount, { - token, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - // Mint some tokens to account - await Actions.token.mintSync(clientWithAccount, { - to: account.address, - amount: parseUnits('1000', 6), - token, - }) - - // First, establish initial liquidity with two-sided mint - await Actions.amm.mintSync(clientWithAccount, { - to: account.address, - userTokenAddress: token, - validatorTokenAddress: 1n, - validatorTokenAmount: parseUnits('100', 6), - }) - - // Get initial pool state - const poolBefore = await Actions.amm.getPool(clientWithAccount, { - userToken: token, - validatorToken: 1n, - }) - - // Add single-sided liquidity (only validatorToken) - const { receipt: mintReceipt, ...mintResult } = await Actions.amm.mintSync( - clientWithAccount, - { - userTokenAddress: token, - validatorTokenAddress: 1n, - validatorTokenAmount: parseUnits('50', 6), - to: account.address, - }, - ) - - expect(mintReceipt).toBeDefined() - // amountUserToken should be 0 for single-sided mint - expect(mintResult.amountUserToken).toBe(0n) - expect(mintResult.amountValidatorToken).toBe(parseUnits('50', 6)) - expect(mintResult.liquidity).toBeGreaterThan(0n) - - // Verify pool reserves - only validatorToken should increase - const poolAfter = await Actions.amm.getPool(clientWithAccount, { - userToken: token, - validatorToken: 1n, - }) - - expect(poolAfter.reserveUserToken).toBe(poolBefore.reserveUserToken) - expect(poolAfter.reserveValidatorToken).toBe( - poolBefore.reserveValidatorToken + parseUnits('50', 6), - ) - expect(poolAfter.totalSupply).toBeGreaterThan(poolBefore.totalSupply) - }) -}) - -describe.skip('burn', () => { - test('default', async () => { - const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount) - - // Get LP balance before burn - const lpBalanceBefore = await Actions.amm.getLiquidityBalance( - clientWithAccount, - { - address: account.address, - userToken: tokenAddress, - validatorToken: 1n, - }, - ) - - // TODO(TEMPO-1183): Remove this janky fix to get some user token in the pool - await Actions.token.transferSync(clientWithAccount, { - to: '0x30D861999070Ae03B9548501DBd573E11A9f59Ee', - amount: 600n, - token: tokenAddress, - feeToken: tokenAddress, - }) - - // Burn half of LP tokens - const { - receipt: burnReceipt, - userToken, - ...burnResult - } = await Actions.amm.burnSync(clientWithAccount, { - userToken: tokenAddress, - validatorToken: 1n, - liquidity: lpBalanceBefore / 2n, - to: account2.address, - }) - const { sender, to, ...rest } = burnResult - - expect(burnReceipt).toBeDefined() - expect(userToken).toBe(tokenAddress) - expect(sender).toBe(account.address) - expect(to).toBe(account2.address) - expect(rest).toMatchInlineSnapshot(` - { - "amountUserToken": 337n, - "amountValidatorToken": 49998664n, - "liquidity": 24999500n, - "validatorToken": "0x20C0000000000000000000000000000000000001", - } - `) - - // Verify LP balance decreased - const lpBalanceAfter = await Actions.amm.getLiquidityBalance( - clientWithAccount, - { - address: account.address, - userToken: tokenAddress, - validatorToken: 1n, - }, - ) - expect(lpBalanceAfter).toBeLessThan(lpBalanceBefore) - expect(lpBalanceAfter).toBe(lpBalanceBefore / 2n) - - // Verify pool reserves decreased - const pool = await Actions.amm.getPool(clientWithAccount, { - userToken: tokenAddress, - validatorToken: 1n, - }) - expect(pool).toMatchInlineSnapshot(` - { - "reserveUserToken": 338n, - "reserveValidatorToken": 50000664n, - "totalSupply": 25000500n, - } - `) - }) -}) - -describe.skip('rebalanceSwap', () => { - test('default', async () => { - const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount) - - // TODO(TEMPO-1183): Remove this janky fix to get some user token in the pool - await Actions.token.transferSync(clientWithAccount, { - to: '0x30D861999070Ae03B9548501DBd573E11A9f59Ee', - amount: 600n, - token: tokenAddress, - feeToken: tokenAddress, - }) - - // Get balance before swap - const balanceBefore = await Actions.token.getBalance(clientWithAccount, { - token: tokenAddress, - account: account2.address, - }) - - // Perform rebalance swap - const { - receipt: swapReceipt, - swapper, - userToken, - ...swapResult - } = await Actions.amm.rebalanceSwapSync(clientWithAccount, { - userToken: tokenAddress, - validatorToken: 1n, - amountOut: 100n, - to: account2.address, - account: account, - }) - expect(swapReceipt).toBeDefined() - expect(userToken).toBe(tokenAddress) - expect(swapper).toBe(account.address) - expect(swapResult).toMatchInlineSnapshot(` - { - "amountIn": 100n, - "amountOut": 100n, - "validatorToken": "0x20C0000000000000000000000000000000000001", - } - `) - - // Verify balance increased - const balanceAfter = await Actions.token.getBalance(clientWithAccount, { - token: tokenAddress, - account: account2.address, - }) - expect(balanceAfter).toBe(balanceBefore + 100n) - }) -}) - -describe.skip('watchRebalanceSwap', () => { - test('default', async () => { - const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount) - - // TODO(TEMPO-1183): Remove this janky fix to get some user token in the pool - await Actions.token.transferSync(clientWithAccount, { - to: '0x30D861999070Ae03B9548501DBd573E11A9f59Ee', - amount: 600n, - token: tokenAddress, - feeToken: tokenAddress, - }) - - let eventArgs: any = null - const unwatch = Actions.amm.watchRebalanceSwap(clientWithAccount, { - onRebalanceSwap: (args) => { - eventArgs = args - }, - }) - - // Perform rebalance swap - await Actions.amm.rebalanceSwapSync(clientWithAccount, { - userToken: tokenAddress, - validatorToken: 1n, - amountOut: 100n, - to: account2.address, - account: account, - }) - - await setTimeout(1000) - - expect(eventArgs).toBeDefined() - expect(eventArgs.userToken.toLowerCase()).toBe(tokenAddress.toLowerCase()) - expect(eventArgs.validatorToken.toLowerCase()).toBe( - '0x20c0000000000000000000000000000000000001', - ) - expect(eventArgs.amountOut).toBe(100n) - - unwatch() - }) -}) - -describe('watchMint', () => { - test('default', async () => { - // Create a new token for testing - const { token } = await Actions.token.createSync(clientWithAccount, { - name: 'Test Token 2', - symbol: 'TEST2', - currency: 'USD', - }) - - // Grant issuer role to mint tokens - await Actions.token.grantRolesSync(clientWithAccount, { - token, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - // Mint some tokens to account - await Actions.token.mintSync(clientWithAccount, { - to: account.address, - amount: parseUnits('1000', 6), - token, - }) - - // Mint USD to account - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: '0x20c0000000000000000000000000000000000001', - functionName: 'transfer', - args: [account.address, parseUnits('1000', 6)], - }) - - let eventArgs: any = null - const unwatch = Actions.amm.watchMint(clientWithAccount, { - onMint: (args) => { - eventArgs = args - }, - }) - - // Add liquidity to pool - await Actions.amm.mintSync(clientWithAccount, { - userTokenAddress: token, - validatorTokenAddress: 1n, - validatorTokenAmount: parseUnits('100', 6), - to: account.address, - }) - - await setTimeout(1000) - - expect(eventArgs).toBeDefined() - expect(eventArgs.userToken.address.toLowerCase()).toBe(token.toLowerCase()) - expect(eventArgs.validatorToken.address.toLowerCase()).toBe( - '0x20c0000000000000000000000000000000000001', - ) - expect(eventArgs.validatorToken.amount).toBe(parseUnits('100', 6)) - - unwatch() - }) -}) - -describe.skip('watchBurn', () => { - test('default', async () => { - const { tokenAddress } = await setupPoolWithLiquidity(clientWithAccount) - - // Get LP balance - const lpBalance = await Actions.amm.getLiquidityBalance(clientWithAccount, { - userToken: tokenAddress, - validatorToken: 1n, - address: account.address, - }) - - // TODO(TEMPO-1183): Remove this janky fix to get some user token in the pool - await Actions.token.transferSync(clientWithAccount, { - to: '0x30D861999070Ae03B9548501DBd573E11A9f59Ee', - amount: 600n, - token: tokenAddress, - feeToken: tokenAddress, - }) - - let eventArgs: any = null - const unwatch = Actions.amm.watchBurn(clientWithAccount, { - onBurn: (args) => { - eventArgs = args - }, - }) - - // Burn LP tokens - await Actions.amm.burnSync(clientWithAccount, { - userToken: tokenAddress, - validatorToken: 1n, - liquidity: lpBalance / 2n, - to: account.address, - }) - - await setTimeout(1000) - - expect(eventArgs).toBeDefined() - expect(eventArgs.userToken.toLowerCase()).toBe(tokenAddress.toLowerCase()) - expect(eventArgs.validatorToken.toLowerCase()).toBe( - '0x20c0000000000000000000000000000000000001', - ) - expect(eventArgs.liquidity).toBe(lpBalance / 2n) - - unwatch() - }) -}) diff --git a/src/viem/Actions/amm.ts b/src/viem/Actions/amm.ts deleted file mode 100644 index 928d50e7..00000000 --- a/src/viem/Actions/amm.ts +++ /dev/null @@ -1,1227 +0,0 @@ -import { PoolId, TokenId } from 'ox/tempo' -import { - type Account, - type Address, - type Chain, - type Client, - type ExtractAbiItem, - type GetEventArgs, - type Hex, - type Log, - type MulticallParameters, - parseEventLogs, - type ReadContractReturnType, - type TransactionReceipt, - type Transport, - type Log as viem_Log, - type WatchContractEventParameters, - type WriteContractReturnType, -} from 'viem' -import { - multicall, - readContract, - watchContractEvent, - writeContract, - writeContractSync, -} from 'viem/actions' -import type { Compute, OneOf, UnionOmit } from '../../internal/types.js' -import * as Abis from '../Abis.js' -import * as Addresses from '../Addresses.js' -import type { ReadParameters, WriteParameters } from '../internal/types.js' -import { defineCall } from '../internal/utils.js' - -/** - * Gets the reserves for a liquidity pool. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const pool = await Actions.amm.getPool(client, { - * userToken: '0x...', - * validatorToken: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The pool reserves. - */ -export async function getPool( - client: Client, - parameters: getPool.Parameters, -): Promise { - const { userToken, validatorToken, ...rest } = parameters - const [pool, totalSupply] = await multicall(client, { - ...rest, - contracts: getPool.calls({ userToken, validatorToken }), - allowFailure: false, - deployless: true, - }) - return { - reserveUserToken: pool.reserveUserToken, - reserveValidatorToken: pool.reserveValidatorToken, - totalSupply, - } -} - -export namespace getPool { - export type Parameters = UnionOmit< - MulticallParameters, - 'allowFailure' | 'contracts' | 'deployless' - > & - Args - - export type Args = { - /** Address or ID of the user token. */ - userToken: TokenId.TokenIdOrAddress - /** Address or ID of the validator token. */ - validatorToken: TokenId.TokenIdOrAddress - } - - export type ReturnValue = Compute<{ - /** Reserve of user token. */ - reserveUserToken: bigint - /** Reserve of validator token. */ - reserveValidatorToken: bigint - /** Total supply of LP tokens. */ - totalSupply: bigint - }> - - /** - * Defines calls to the `getPool` and `totalSupply` functions. - * - * @param args - Arguments. - * @returns The calls. - */ - export function calls(args: Args) { - const { userToken, validatorToken } = args - return [ - defineCall({ - address: Addresses.feeManager, - abi: Abis.feeAmm, - args: [TokenId.toAddress(userToken), TokenId.toAddress(validatorToken)], - functionName: 'getPool', - }), - defineCall({ - address: Addresses.feeManager, - abi: Abis.feeAmm, - args: [PoolId.from({ userToken, validatorToken })], - functionName: 'totalSupply', - }), - ] as const - } -} - -/** - * Gets the LP token balance for an account in a specific pool. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const poolId = await Actions.amm.getPoolId(client, { - * userToken: '0x...', - * validatorToken: '0x...', - * }) - * - * const balance = await Actions.amm.getLiquidityBalance(client, { - * poolId, - * address: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The LP token balance. - */ -export async function getLiquidityBalance( - client: Client, - parameters: getLiquidityBalance.Parameters, -): Promise { - const { address, poolId, userToken, validatorToken, ...rest } = parameters - return readContract(client, { - ...rest, - ...getLiquidityBalance.call({ - address, - poolId, - userToken, - validatorToken, - } as never), - }) -} - -export namespace getLiquidityBalance { - export type Parameters = ReadParameters & Args - - export type Args = { - /** Address to check balance for. */ - address: Address - } & OneOf< - | { - /** Pool ID. */ - poolId: Hex - } - | { - /** User token. */ - userToken: TokenId.TokenIdOrAddress - /** Validator token. */ - validatorToken: TokenId.TokenIdOrAddress - } - > - - export type ReturnValue = ReadContractReturnType< - typeof Abis.feeAmm, - 'liquidityBalances', - never - > - - /** - * Defines a call to the `liquidityBalances` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { address } = args - const poolId = (() => { - if ('poolId' in args && args.poolId) return args.poolId! - if ('userToken' in args && 'validatorToken' in args) - return PoolId.from({ - userToken: args.userToken, - validatorToken: args.validatorToken, - }) - throw new Error( - '`poolId`, or `userToken` and `validatorToken` must be provided.', - ) - })() - return defineCall({ - address: Addresses.feeManager, - abi: Abis.feeAmm, - args: [poolId, address], - functionName: 'liquidityBalances', - }) - } -} - -/** - * Performs a rebalance swap from validator token to user token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.amm.rebalanceSwap(client, { - * userToken: '0x...', - * validatorToken: '0x...', - * amountOut: 100n, - * to: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function rebalanceSwap< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: rebalanceSwap.Parameters, -): Promise { - return rebalanceSwap.inner(writeContract, client, parameters) -} - -export namespace rebalanceSwap { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount of user token to receive. */ - amountOut: bigint - /** Address to send the user token to. */ - to: Address - /** Address or ID of the user token. */ - userToken: TokenId.TokenIdOrAddress - /** Address or ID of the validator token. */ - validatorToken: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: rebalanceSwap.Parameters, - ): Promise> { - const { userToken, validatorToken, amountOut, to, ...rest } = parameters - const call = rebalanceSwap.call({ - userToken, - validatorToken, - amountOut, - to, - }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `rebalanceSwap` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.amm.rebalanceSwap.call({ - * userToken: '0x20c0...beef', - * validatorToken: '0x20c0...babe', - * amountOut: 100n, - * to: '0xfeed...fede', - * }), - * actions.amm.rebalanceSwap.call({ - * userToken: '0x20c0...babe', - * validatorToken: '0x20c0...babe', - * amountOut: 100n, - * to: '0xfeed...fede', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { userToken, validatorToken, amountOut, to } = args - return defineCall({ - address: Addresses.feeManager, - abi: Abis.feeAmm, - functionName: 'rebalanceSwap', - args: [ - TokenId.toAddress(userToken), - TokenId.toAddress(validatorToken), - amountOut, - to, - ], - }) - } - - /** - * Extracts the `RebalanceSwap` event from logs. - * - * @param logs - The logs. - * @returns The `RebalanceSwap` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.feeAmm, - logs, - eventName: 'RebalanceSwap', - strict: true, - }) - if (!log) throw new Error('`RebalanceSwap` event not found.') - return log - } -} - -/** - * Performs a rebalance swap from validator token to user token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.amm.rebalanceSwapSync(client, { - * userToken: '0x...', - * validatorToken: '0x...', - * amountOut: 100n, - * to: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function rebalanceSwapSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: rebalanceSwapSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await rebalanceSwap.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = rebalanceSwap.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace rebalanceSwapSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = rebalanceSwap.Parameters - - export type Args = rebalanceSwap.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.feeAmm, - 'RebalanceSwap', - { IndexedOnly: false; Required: true } - > & { - /** Transaction receipt. */ - receipt: TransactionReceipt - } - > -} - -/** - * Adds liquidity to a pool. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.amm.mint(client, { - * userTokenAddress: '0x20c0...beef', - * validatorTokenAddress: '0x20c0...babe', - * validatorTokenAmount: 100n, - * to: '0xfeed...fede', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function mint< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: mint.Parameters, -): Promise { - return mint.inner(writeContract, client, parameters) -} - -export namespace mint { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Address to mint LP tokens to. */ - to: Address - /** User token address. */ - userTokenAddress: TokenId.TokenIdOrAddress - /** Validator token address. */ - validatorTokenAddress: TokenId.TokenIdOrAddress - /** Amount of validator token to add. */ - validatorTokenAmount: bigint - } - - export type ReturnValue = WriteContractReturnType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: mint.Parameters, - ): Promise> { - const { - to, - userTokenAddress, - validatorTokenAddress, - validatorTokenAmount, - ...rest - } = parameters - const call = mint.call({ - to, - userTokenAddress, - validatorTokenAddress, - validatorTokenAmount, - }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `mint` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.amm.mint.call({ - * userTokenAddress: '0x20c0...beef', - * validatorTokenAddress: '0x20c0...babe', - * validatorTokenAmount: 100n, - * to: '0xfeed...fede', - * }), - * actions.amm.mint.call({ - * userTokenAddress: '0x20c0...babe', - * validatorTokenAddress: '0x20c0...babe', - * validatorTokenAmount: 100n, - * to: '0xfeed...fede', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { - to, - userTokenAddress, - validatorTokenAddress, - validatorTokenAmount, - } = args - return defineCall({ - address: Addresses.feeManager, - abi: Abis.feeAmm, - functionName: 'mintWithValidatorToken', - args: [ - TokenId.toAddress(userTokenAddress), - TokenId.toAddress(validatorTokenAddress), - validatorTokenAmount, - to, - ], - }) - } - - /** - * Extracts the `Mint` event from logs. - * - * @param logs - The logs. - * @returns The `Mint` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.feeAmm, - logs, - eventName: 'Mint', - strict: true, - }) - if (!log) throw new Error('`Mint` event not found.') - return log - } -} - -/** - * Adds liquidity to a pool. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.amm.mint(client, { - * userTokenAddress: '0x20c0...beef', - * validatorTokenAddress: '0x20c0...babe', - * validatorTokenAmount: 100n, - * to: '0xfeed...fede', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function mintSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: mintSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await mint.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = mint.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace mintSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = mint.Parameters - - export type Args = mint.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.feeAmm, - 'Mint', - { IndexedOnly: false; Required: true } - > & { - /** Transaction receipt. */ - receipt: TransactionReceipt - } - > -} - -/** - * Removes liquidity from a pool. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.amm.burn(client, { - * userToken: '0x20c0...beef', - * validatorToken: '0x20c0...babe', - * liquidity: 50n, - * to: '0xfeed...fede', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function burn< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: burn.Parameters, -): Promise { - return burn.inner(writeContract, client, parameters) -} - -export namespace burn { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount of LP tokens to burn. */ - liquidity: bigint - /** Address to send tokens to. */ - to: Address - /** Address or ID of the user token. */ - userToken: TokenId.TokenIdOrAddress - /** Address or ID of the validator token. */ - validatorToken: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: burn.Parameters, - ): Promise> { - const { liquidity, to, userToken, validatorToken, ...rest } = parameters - const call = burn.call({ liquidity, to, userToken, validatorToken }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `burn` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.amm.burn.call({ - * liquidity: 100n, - * to: '0xfeed...fede', - * userToken: '0x20c0...beef', - * validatorToken: '0x20c0...babe', - * }), - * actions.amm.burn.call({ - * liquidity: 100n, - * to: '0xfeed...fede', - * userToken: '0x20c0...babe', - * validatorToken: '0x20c0...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { liquidity, to, userToken, validatorToken } = args - return defineCall({ - address: Addresses.feeManager, - abi: Abis.feeAmm, - functionName: 'burn', - args: [ - TokenId.toAddress(userToken), - TokenId.toAddress(validatorToken), - liquidity, - to, - ], - }) - } - - /** - * Extracts the `Burn` event from logs. - * - * @param logs - The logs. - * @returns The `Burn` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.feeAmm, - logs, - eventName: 'Burn', - strict: true, - }) - if (!log) throw new Error('`Burn` event not found.') - return log - } -} - -/** - * Removes liquidity from a pool. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.amm.burnSync(client, { - * userToken: '0x20c0...beef', - * validatorToken: '0x20c0...babe', - * liquidity: 50n, - * to: '0xfeed...fede', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function burnSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: burnSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await burn.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = burn.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace burnSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = burn.Parameters - - export type Args = burn.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.feeAmm, - 'Burn', - { IndexedOnly: false; Required: true } - > & { - /** Transaction receipt. */ - receipt: TransactionReceipt - } - > -} - -/** - * Watches for rebalance swap events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.amm.watchRebalanceSwap(client, { - * onRebalanceSwap: (args, log) => { - * console.log('Rebalance swap:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchRebalanceSwap< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchRebalanceSwap.Parameters, -) { - const { onRebalanceSwap, userToken, validatorToken, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.feeManager, - abi: Abis.feeAmm, - eventName: 'RebalanceSwap', - args: - userToken !== undefined && validatorToken !== undefined - ? { - userToken: TokenId.toAddress(userToken), - validatorToken: TokenId.toAddress(validatorToken), - } - : undefined, - onLogs: (logs) => { - for (const log of logs) onRebalanceSwap(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchRebalanceSwap { - export type Args = GetEventArgs< - typeof Abis.feeAmm, - 'RebalanceSwap', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a rebalance swap occurs. */ - onRebalanceSwap: (args: Args, log: Log) => void - /** Address or ID of the user token to filter events. */ - userToken?: TokenId.TokenIdOrAddress | undefined - /** Address or ID of the validator token to filter events. */ - validatorToken?: TokenId.TokenIdOrAddress | undefined - } -} - -/** - * Watches for fee swap events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.amm.watchFeeSwap(client, { - * onFeeSwap: (args, log) => { - * console.log('Fee swap:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchFeeSwap< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchFeeSwap.Parameters, -) { - const { onFeeSwap, userToken, validatorToken, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.feeManager, - abi: Abis.feeAmm, - eventName: 'FeeSwap', - args: - userToken !== undefined && validatorToken !== undefined - ? { - userToken: TokenId.toAddress(userToken), - validatorToken: TokenId.toAddress(validatorToken), - } - : undefined, - onLogs: (logs) => { - for (const log of logs) onFeeSwap(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchFeeSwap { - export type Args = GetEventArgs< - typeof Abis.feeAmm, - 'FeeSwap', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a fee swap occurs. */ - onFeeSwap: (args: Args, log: Log) => void - /** Address or ID of the user token to filter events. */ - userToken?: TokenId.TokenIdOrAddress | undefined - /** Address or ID of the validator token to filter events. */ - validatorToken?: TokenId.TokenIdOrAddress | undefined - } -} - -/** - * Watches for liquidity mint events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.amm.watchMint(client, { - * onMint: (args, log) => { - * console.log('Liquidity added:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchMint< - chain extends Chain | undefined, - account extends Account | undefined, ->(client: Client, parameters: watchMint.Parameters) { - const { onMint, sender, userToken, validatorToken, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.feeManager, - abi: Abis.feeAmm, - eventName: 'Mint', - args: { - ...(sender !== undefined && { - sender: TokenId.toAddress(sender), - }), - ...(userToken !== undefined && { - userToken: TokenId.toAddress(userToken), - }), - ...(validatorToken !== undefined && { - validatorToken: TokenId.toAddress(validatorToken), - }), - }, - onLogs: (logs) => { - for (const log of logs) - onMint( - { - liquidity: log.args.liquidity, - sender: log.args.sender, - userToken: { - address: log.args.userToken, - amount: log.args.amountUserToken, - }, - validatorToken: { - address: log.args.validatorToken, - amount: log.args.amountValidatorToken, - }, - }, - log, - ) - }, - strict: true, - }) -} - -export declare namespace watchMint { - export type Args = { - liquidity: bigint - sender: Address - userToken: { - address: Address - amount: bigint - } - validatorToken: { - address: Address - amount: bigint - } - } - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when liquidity is added. */ - onMint: (args: Args, log: Log) => void - /** Address or ID of the sender to filter events. */ - sender?: TokenId.TokenIdOrAddress | undefined - /** Address or ID of the user token to filter events. */ - userToken?: TokenId.TokenIdOrAddress | undefined - /** Address or ID of the validator token to filter events. */ - validatorToken?: TokenId.TokenIdOrAddress | undefined - } -} - -/** - * Watches for liquidity burn events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.amm.watchBurn(client, { - * onBurn: (args, log) => { - * console.log('Liquidity removed:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchBurn< - chain extends Chain | undefined, - account extends Account | undefined, ->(client: Client, parameters: watchBurn.Parameters) { - const { onBurn, userToken, validatorToken, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.feeManager, - abi: Abis.feeAmm, - eventName: 'Burn', - args: - userToken !== undefined && validatorToken !== undefined - ? { - userToken: TokenId.toAddress(userToken), - validatorToken: TokenId.toAddress(validatorToken), - } - : undefined, - onLogs: (logs) => { - for (const log of logs) onBurn(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchBurn { - export type Args = GetEventArgs< - typeof Abis.feeAmm, - 'Burn', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when liquidity is removed. */ - onBurn: (args: Args, log: Log) => void - /** Address or ID of the user token to filter events. */ - userToken?: TokenId.TokenIdOrAddress | undefined - /** Address or ID of the validator token to filter events. */ - validatorToken?: TokenId.TokenIdOrAddress | undefined - } -} diff --git a/src/viem/Actions/dex.test.ts b/src/viem/Actions/dex.test.ts deleted file mode 100644 index 9b114f7c..00000000 --- a/src/viem/Actions/dex.test.ts +++ /dev/null @@ -1,1549 +0,0 @@ -import { Actions, Tick } from 'tempo.ts/viem' -import { parseUnits } from 'viem' -import { describe, expect, test } from 'vitest' -import { - accounts, - clientWithAccount, - setupTokenPair, -} from '../../../test/viem/config.js' - -describe('buy', () => { - test('default', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Place ask order to create liquidity - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('500', 6), - type: 'sell', - tick: Tick.fromPrice('1.001'), - }) - - // Get initial balances - const baseBalanceBefore = await Actions.token.getBalance( - clientWithAccount, - { - token: base, - }, - ) - - // Buy base tokens with quote tokens - const { receipt } = await Actions.dex.buySync(clientWithAccount, { - tokenIn: quote, - tokenOut: base, - amountOut: parseUnits('100', 6), - maxAmountIn: parseUnits('150', 6), - }) - - expect(receipt).toBeDefined() - expect(receipt.status).toBe('success') - - // Verify balances changed - const baseBalanceAfter = await Actions.token.getBalance(clientWithAccount, { - token: base, - }) - - // Should have received base tokens - expect(baseBalanceAfter).toBeGreaterThan(baseBalanceBefore) - }) - - test('behavior: respects maxAmountIn', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Place ask order at high price - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('500', 6), - type: 'sell', - tick: Tick.fromPrice('1.01'), // 1% above peg - }) - - // Try to buy with insufficient maxAmountIn - should fail - await expect( - Actions.dex.buySync(clientWithAccount, { - tokenIn: quote, - tokenOut: base, - amountOut: parseUnits('100', 6), - maxAmountIn: parseUnits('50', 6), // Way too low for 1% premium - }), - ).rejects.toThrow('The contract function "swapExactAmountOut" reverted') - }) - - test('behavior: fails with insufficient liquidity', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Don't place any orders - no liquidity - - // Try to buy - should fail due to no liquidity - await expect( - Actions.dex.buySync(clientWithAccount, { - tokenIn: quote, - tokenOut: base, - amountOut: parseUnits('100', 6), - maxAmountIn: parseUnits('150', 6), - }), - ).rejects.toThrow('The contract function "swapExactAmountOut" reverted') - }) -}) - -describe('cancel', () => { - test('default', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Place a bid order - const { orderId } = await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }) - - // Check initial DEX balance (should be 0) - const dexBalanceBefore = await Actions.dex.getBalance(clientWithAccount, { - account: clientWithAccount.account.address, - token: quote, - }) - expect(dexBalanceBefore).toBe(0n) - - // Cancel the order - const { receipt, orderId: returnedOrderId } = await Actions.dex.cancelSync( - clientWithAccount, - { - orderId, - }, - ) - - expect(receipt).toBeDefined() - expect(receipt.status).toBe('success') - expect(returnedOrderId).toBe(orderId) - - // Check DEX balance after cancel - tokens should be refunded to internal balance - const dexBalanceAfter = await Actions.dex.getBalance(clientWithAccount, { - account: clientWithAccount.account.address, - token: quote, - }) - expect(dexBalanceAfter).toBeGreaterThan(0n) - }) - - test('behavior: only maker can cancel', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - // Account places order - const { orderId } = await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }) - - // Create another account - const account2 = accounts[1] - - // Transfer gas to account2 - await Actions.token.transferSync(clientWithAccount, { - to: account2.address, - amount: parseUnits('1', 6), - token: 1n, - }) - - // Account2 tries to cancel - should fail - await expect( - Actions.dex.cancelSync(clientWithAccount, { - account: account2, - orderId, - }), - ).rejects.toThrow('The contract function "cancel" reverted') - }) - - test('behavior: cannot cancel non-existent order', async () => { - await setupTokenPair(clientWithAccount) - - // Try to cancel an order that doesn't exist - await expect( - Actions.dex.cancelSync(clientWithAccount, { - orderId: 999n, - }), - ).rejects.toThrow('The contract function "cancel" reverted') - }) -}) - -describe('createPair', () => { - test('default', async () => { - const { token: baseToken } = await Actions.token.createSync( - clientWithAccount, - { - name: 'Test Base Token', - symbol: 'BASE', - currency: 'USD', - }, - ) - - const { receipt, key, base, quote } = await Actions.dex.createPairSync( - clientWithAccount, - { - base: baseToken, - }, - ) - - expect(receipt).toBeDefined() - expect(receipt.status).toBe('success') - expect(key).toBeDefined() - expect(base).toBe(baseToken) - expect(quote).toBeDefined() - }) -}) - -describe('getBalance', () => { - test('default', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Initial balance should be 0 - const initialBalance = await Actions.dex.getBalance(clientWithAccount, { - account: clientWithAccount.account.address, - token: quote, - }) - expect(initialBalance).toBe(0n) - - // Place and cancel order to create internal balance - const { orderId } = await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('50', 6), - type: 'buy', - tick: Tick.fromPrice('1.0005'), - }) - - await Actions.dex.cancelSync(clientWithAccount, { - orderId, - }) - - // Now balance should be > 0 (refunded quote tokens) - const balance = await Actions.dex.getBalance(clientWithAccount, { - account: clientWithAccount.account.address, - token: quote, - }) - expect(balance).toBeGreaterThan(0n) - }) - - test('behavior: check different account', async () => { - const { quote } = await setupTokenPair(clientWithAccount) - - const account2 = accounts[1] - - // Check account2's balance (should be 0) - const balance = await Actions.dex.getBalance(clientWithAccount, { - account: account2.address, - token: quote, - }) - expect(balance).toBe(0n) - }) - - test('behavior: balances are per-token', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Create balance in quote token - const { orderId } = await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }) - await Actions.dex.cancelSync(clientWithAccount, { orderId }) - - // Check quote balance (should have refunded tokens) - const quoteBalance = await Actions.dex.getBalance(clientWithAccount, { - account: clientWithAccount.account.address, - token: quote, - }) - expect(quoteBalance).toBeGreaterThan(0n) - - // Check base balance (should still be 0) - const baseBalance = await Actions.dex.getBalance(clientWithAccount, { - account: clientWithAccount.account.address, - token: base, - }) - expect(baseBalance).toBe(0n) - }) -}) - -describe('getBuyQuote', () => { - test('default', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Place ask orders to create liquidity - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('500', 6), - type: 'sell', - tick: Tick.fromPrice('1.001'), - }) - - // Get quote for buying base tokens - const amountIn = await Actions.dex.getBuyQuote(clientWithAccount, { - tokenIn: quote, - tokenOut: base, - amountOut: parseUnits('100', 6), - }) - - expect(amountIn).toBeGreaterThan(0n) - // Should be approximately 100 * 1.001 = 100.1 - expect(amountIn).toBeGreaterThan(parseUnits('100', 6)) - }) - - test('behavior: fails with no liquidity', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // No orders placed - no liquidity - - // Quote should fail - await expect( - Actions.dex.getBuyQuote(clientWithAccount, { - tokenIn: quote, - tokenOut: base, - amountOut: parseUnits('100', 6), - }), - ).rejects.toThrow( - 'The contract function "quoteSwapExactAmountOut" reverted', - ) - }) -}) - -describe('getOrder', () => { - test('default', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - // Place an order to get an order ID - const { orderId } = await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }) - - // Get the order details - const order = await Actions.dex.getOrder(clientWithAccount, { - orderId, - }) - - expect(order).toBeDefined() - expect(order.maker).toBe(clientWithAccount.account.address) - expect(order.isBid).toBe(true) - expect(order.tick).toBe(Tick.fromPrice('1.001')) - expect(order.amount).toBe(parseUnits('100', 6)) - expect(order.remaining).toBe(parseUnits('100', 6)) - expect(order.isFlip).toBe(false) - }) - - test('behavior: returns flip order details', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - // Place a flip order - const { orderId } = await Actions.dex.placeFlipSync(clientWithAccount, { - token: base, - amount: parseUnits('50', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - flipTick: Tick.fromPrice('1.002'), - }) - - // Get the order details - const order = await Actions.dex.getOrder(clientWithAccount, { - orderId, - }) - - expect(order).toBeDefined() - expect(order.maker).toBe(clientWithAccount.account.address) - expect(order.isBid).toBe(true) - expect(order.tick).toBe(Tick.fromPrice('1.001')) - expect(order.amount).toBe(parseUnits('50', 6)) - expect(order.isFlip).toBe(true) - expect(order.flipTick).toBe(Tick.fromPrice('1.002')) - }) - - test('behavior: fails for non-existent order', async () => { - await setupTokenPair(clientWithAccount) - - // Try to get an order that doesn't exist - await expect( - Actions.dex.getOrder(clientWithAccount, { - orderId: 999n, - }), - ).rejects.toThrow('The contract function "getOrder" reverted') - }) - - test('behavior: reflects order state after partial fill', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Place a large sell order - const { orderId } = await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('500', 6), - type: 'sell', - tick: Tick.fromPrice('1.001'), - }) - - // Get initial order state - const orderBefore = await Actions.dex.getOrder(clientWithAccount, { - orderId, - }) - expect(orderBefore.amount).toBe(parseUnits('500', 6)) - expect(orderBefore.remaining).toBe(parseUnits('500', 6)) - - // Partially fill the order with a buy - await Actions.dex.buySync(clientWithAccount, { - tokenIn: quote, - tokenOut: base, - amountOut: parseUnits('100', 6), - maxAmountIn: parseUnits('150', 6), - }) - - // Get order state after partial fill - const orderAfter = await Actions.dex.getOrder(clientWithAccount, { - orderId, - }) - expect(orderAfter.amount).toBe(parseUnits('500', 6)) // amount unchanged - expect(orderAfter.remaining).toBeLessThan(parseUnits('500', 6)) // remaining decreased - }) - - test('behavior: linked list pointers for multiple orders at same tick', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - const tick = Tick.fromPrice('1.001') - - // Place first order - const { orderId: orderId1 } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick, - }, - ) - - // Place second order at same tick - const { orderId: orderId2 } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('50', 6), - type: 'buy', - tick, - }, - ) - - // Get first order - const order1 = await Actions.dex.getOrder(clientWithAccount, { - orderId: orderId1, - }) - expect(order1.prev).toBe(0n) // should be 0 as it's first - expect(order1.next).toBe(orderId2) // should point to second order - - // Get second order - const order2 = await Actions.dex.getOrder(clientWithAccount, { - orderId: orderId2, - }) - expect(order2.prev).toBe(orderId1) // should point to first order - expect(order2.next).toBe(0n) // should be 0 as it's last - }) -}) - -describe('getOrderbook', () => { - test('default', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Get orderbook information - const book = await Actions.dex.getOrderbook(clientWithAccount, { - base, - quote, - }) - - expect(book).toBeDefined() - expect(book.base).toBe(base) - expect(book.quote).toBe(quote) - expect(book.bestBidTick).toBeDefined() - expect(book.bestAskTick).toBeDefined() - }) - - test('behavior: shows best bid and ask after orders placed', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - const bidTick = Tick.fromPrice('0.999') - const askTick = Tick.fromPrice('1.001') - - // Place a bid order - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: bidTick, - }) - - // Place an ask order - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'sell', - tick: askTick, - }) - - // Get orderbook - const book = await Actions.dex.getOrderbook(clientWithAccount, { - base, - quote, - }) - - expect(book.bestBidTick).toBe(bidTick) - expect(book.bestAskTick).toBe(askTick) - }) - - test('behavior: best ticks update after better orders placed', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Place initial bid at 0.999 - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('0.999'), - }) - - // Get orderbook - const bookBefore = await Actions.dex.getOrderbook(clientWithAccount, { - base, - quote, - }) - expect(bookBefore.bestBidTick).toBe(Tick.fromPrice('0.999')) - - // Place better bid at 1.0 - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.0'), - }) - - // Get orderbook again - const bookAfter = await Actions.dex.getOrderbook(clientWithAccount, { - base, - quote, - }) - expect(bookAfter.bestBidTick).toBe(Tick.fromPrice('1.0')) - }) - - test.skip('behavior: best ticks update after order cancellation', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Place two bid orders at different ticks - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('50', 6), - type: 'buy', - tick: Tick.fromPrice('0.999'), - }) - - const { orderId } = await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.0'), - }) - - // Get orderbook - best bid should be 1.0 - const bookBefore = await Actions.dex.getOrderbook(clientWithAccount, { - base, - quote, - }) - expect(bookBefore.bestBidTick).toBe(Tick.fromPrice('1.0')) - - // Cancel the better order - await Actions.dex.cancelSync(clientWithAccount, { orderId }) - - // Get orderbook again - best bid should fall back to 0.999 - const bookAfter = await Actions.dex.getOrderbook(clientWithAccount, { - base, - quote, - }) - expect(bookAfter.bestBidTick).toBe(Tick.fromPrice('0.999')) - }) - - test('behavior: multiple pairs have independent orderbooks', async () => { - const { base: base1, quote: quote1 } = - await setupTokenPair(clientWithAccount) - const { base: base2, quote: quote2 } = - await setupTokenPair(clientWithAccount) - - // Place order on first pair - await Actions.dex.placeSync(clientWithAccount, { - token: base1, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }) - - // Place order on second pair at different tick - await Actions.dex.placeSync(clientWithAccount, { - token: base2, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('0.999'), - }) - - // Get orderbooks - const book1 = await Actions.dex.getOrderbook(clientWithAccount, { - base: base1, - quote: quote1, - }) - - const book2 = await Actions.dex.getOrderbook(clientWithAccount, { - base: base2, - quote: quote2, - }) - - // Each pair should have its own best tick - expect(book1.bestBidTick).toBe(Tick.fromPrice('1.001')) - expect(book2.bestBidTick).toBe(Tick.fromPrice('0.999')) - }) -}) - -describe('getTickLevel', () => { - test('default', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - const tick = Tick.fromPrice('1.001') - - // Place an order to create liquidity at this tick - const { orderId } = await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick, - }) - - // Get the price level - const level = await Actions.dex.getTickLevel(clientWithAccount, { - base, - tick, - isBid: true, - }) - - expect(level).toBeDefined() - expect(level.head).toBe(orderId) // head should be our order - expect(level.tail).toBe(orderId) // tail should also be our order (only one) - expect(level.totalLiquidity).toBeGreaterThan(0n) - }) - - test('behavior: empty price level', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - const tick = Tick.fromPrice('1.001') - - // Query a tick with no orders - const level = await Actions.dex.getTickLevel(clientWithAccount, { - base, - tick, - isBid: true, - }) - - expect(level).toBeDefined() - expect(level.head).toBe(0n) - expect(level.tail).toBe(0n) - expect(level.totalLiquidity).toBe(0n) - }) - - test('behavior: multiple orders at same tick', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - const tick = Tick.fromPrice('1.001') - - // Place first order - const { orderId: orderId1 } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick, - }, - ) - - // Place second order at same tick - const { orderId: orderId2 } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('50', 6), - type: 'buy', - tick, - }, - ) - - // Get the price level - const level = await Actions.dex.getTickLevel(clientWithAccount, { - base, - tick, - isBid: true, - }) - - expect(level.head).toBe(orderId1) // head should be first order - expect(level.tail).toBe(orderId2) // tail should be last order - // Total liquidity should be sum of both orders (approximately) - expect(level.totalLiquidity).toBeGreaterThan(parseUnits('145', 6)) - }) - - test('behavior: bid vs ask sides', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - const tick = Tick.fromPrice('1.001') - - // Place a buy order (bid) - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick, - }) - - // Place a sell order (ask) at same tick - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('50', 6), - type: 'sell', - tick, - }) - - // Get bid side - const bidLevel = await Actions.dex.getTickLevel(clientWithAccount, { - base, - tick, - isBid: true, - }) - - // Get ask side - const askLevel = await Actions.dex.getTickLevel(clientWithAccount, { - base, - tick, - isBid: false, - }) - - // Both should have liquidity but different amounts - expect(bidLevel.totalLiquidity).toBeGreaterThan(0n) - expect(askLevel.totalLiquidity).toBeGreaterThan(0n) - expect(bidLevel.head).not.toBe(askLevel.head) - }) - - test('behavior: liquidity changes after order cancellation', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - const tick = Tick.fromPrice('1.001') - - // Place orders - const { orderId: orderId1 } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick, - }, - ) - - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('50', 6), - type: 'buy', - tick, - }) - - // Get level before cancellation - const levelBefore = await Actions.dex.getTickLevel(clientWithAccount, { - base, - tick, - isBid: true, - }) - - // Cancel first order - await Actions.dex.cancelSync(clientWithAccount, { - orderId: orderId1, - }) - - // Get level after cancellation - const levelAfter = await Actions.dex.getTickLevel(clientWithAccount, { - base, - tick, - isBid: true, - }) - - // Total liquidity should decrease - expect(levelAfter.totalLiquidity).toBeLessThan(levelBefore.totalLiquidity) - }) - - test('behavior: liquidity changes after partial fill', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - const tick = Tick.fromPrice('1.001') - - // Place sell order - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('500', 6), - type: 'sell', - tick, - }) - - // Get level before fill - const levelBefore = await Actions.dex.getTickLevel(clientWithAccount, { - base, - tick, - isBid: false, - }) - - // Partially fill the order - await Actions.dex.buySync(clientWithAccount, { - tokenIn: quote, - tokenOut: base, - amountOut: parseUnits('100', 6), - maxAmountIn: parseUnits('150', 6), - }) - - // Get level after fill - const levelAfter = await Actions.dex.getTickLevel(clientWithAccount, { - base, - tick, - isBid: false, - }) - - // Total liquidity should decrease - expect(levelAfter.totalLiquidity).toBeLessThan(levelBefore.totalLiquidity) - }) - - test('behavior: tick at boundaries', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - // Place order at min tick - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('10', 6), - type: 'sell', - tick: Tick.minTick, - }) - - // Query min tick - const minLevel = await Actions.dex.getTickLevel(clientWithAccount, { - base, - tick: Tick.minTick, - isBid: false, - }) - expect(minLevel.totalLiquidity).toBeGreaterThan(0n) - - // Place order at max tick - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('10', 6), - type: 'buy', - tick: Tick.maxTick, - }) - - // Query max tick - const maxLevel = await Actions.dex.getTickLevel(clientWithAccount, { - base, - tick: Tick.maxTick, - isBid: true, - }) - expect(maxLevel.totalLiquidity).toBeGreaterThan(0n) - }) -}) - -describe('getSellQuote', () => { - test('default', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Place bid orders to create liquidity - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('500', 6), - type: 'buy', - tick: Tick.fromPrice('0.999'), - }) - - // Get quote for selling base tokens - const amountOut = await Actions.dex.getSellQuote(clientWithAccount, { - tokenIn: base, - tokenOut: quote, - amountIn: parseUnits('100', 6), - }) - - expect(amountOut).toBeGreaterThan(0n) - // Should be approximately 100 * 0.999 = 99.9 - expect(amountOut).toBeLessThan(parseUnits('100', 6)) - }) - - test('behavior: fails with no liquidity', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Quote should fail with no liquidity - await expect( - Actions.dex.getSellQuote(clientWithAccount, { - tokenIn: base, - tokenOut: quote, - amountIn: parseUnits('100', 6), - }), - ).rejects.toThrow('The contract function "quoteSwapExactAmountIn" reverted') - }) -}) - -describe('place', () => { - test('default', async () => { - // Setup token pair - const { base } = await setupTokenPair(clientWithAccount) - - // Place a sell order - const { receipt, orderId, token, ...result } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('100', 6), - type: 'sell', - tick: Tick.fromPrice('1.001'), - }, - ) - - expect(receipt).toBeDefined() - expect(receipt.status).toBe('success') - expect(orderId).toBeGreaterThan(0n) - expect(token).toBe(base) - expect(result).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "isBid": false, - "maker": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "tick": 100, - } - `) - - // Place a buy order - const { - receipt: receipt2, - orderId: orderId2, - token: token2, - ...result2 - } = await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }) - expect(receipt2.status).toBe('success') - expect(orderId2).toBeGreaterThan(0n) - expect(token2).toBe(base) - expect(result2).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "isBid": true, - "maker": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "tick": 100, - } - `) - }) - - test('behavior: tick at boundaries', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - // Test at min tick (-2000) - const { receipt: receipt1, ...result1 } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('10', 6), - type: 'sell', - tick: Tick.minTick, - }, - ) - expect(receipt1.status).toBe('success') - expect(result1.tick).toBe(-2000) - - // Test at max tick (2000) - const { receipt: receipt2, ...result2 } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('10', 6), - type: 'buy', - tick: Tick.maxTick, - }, - ) - expect(receipt2.status).toBe('success') - expect(result2.tick).toBe(2000) - }) - - test('behavior: tick validation fails outside bounds', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - // Test tick above max tix should fail - await expect( - Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('10', 6), - type: 'buy', - tick: Tick.maxTick + 1, - }), - ).rejects.toThrow('The contract function "place" reverted') - - // Test tick below min tick should fail - await expect( - Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('10', 6), - type: 'sell', - tick: Tick.minTick - 1, - }), - ).rejects.toThrow('The contract function "place" reverted') - }) - - test('behavior: transfers from wallet', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Get balances before placing order - const baseBalanceBefore = await Actions.token.getBalance( - clientWithAccount, - { - token: base, - }, - ) - const quoteBalanceBefore = await Actions.token.getBalance( - clientWithAccount, - { - token: quote, - }, - ) - - // Place a buy order - should transfer quote tokens to escrow - const orderAmount = parseUnits('100', 6) - const tick = Tick.fromPrice('1.001') - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: orderAmount, - type: 'buy', - tick, - }) - - // Get balances after placing order - const baseBalanceAfter = await Actions.token.getBalance(clientWithAccount, { - token: base, - }) - const quoteBalanceAfter = await Actions.token.getBalance( - clientWithAccount, - { - token: quote, - }, - ) - - // Base token balance should be unchanged (we're buying base, not selling) - expect(baseBalanceAfter).toBe(baseBalanceBefore) - - // Quote token balance should decrease (escrowed for the bid) - // Amount = orderAmount * (1 + tick/1000) for bids - const expectedQuoteEscrowed = - (orderAmount * BigInt(100000 + tick)) / BigInt(100000) - expect(quoteBalanceBefore - quoteBalanceAfter).toBeGreaterThanOrEqual( - expectedQuoteEscrowed, - ) - }) - - test('behavior: multiple orders at same tick', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - const tick = Tick.fromPrice('1.0005') - - // Place first order - const { orderId: orderId1 } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick, - }, - ) - - // Place second order at same tick - const { orderId: orderId2 } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('50', 6), - type: 'buy', - tick, - }, - ) - - // Order IDs should be different and sequential - expect(orderId2).toBeGreaterThan(orderId1) - }) -}) - -describe('placeFlip', () => { - test('default', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - // Place a flip bid order - const { receipt, orderId, token, ...result } = - await Actions.dex.placeFlipSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - flipTick: Tick.fromPrice('1.002'), - }) - - expect(receipt).toBeDefined() - expect(receipt.status).toBe('success') - expect(orderId).toBeGreaterThan(0n) - expect(token).toBe(base) - expect(result.flipTick).toBe(Tick.fromPrice('1.002')) - expect(result).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "flipTick": 200, - "isBid": true, - "maker": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "tick": 100, - } - `) - }) - - test('behavior: flip bid requires flipTick > tick', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - // Valid: flipTick > tick for bid - const { receipt: receipt1 } = await Actions.dex.placeFlipSync( - clientWithAccount, - { - token: base, - amount: parseUnits('10', 6), - type: 'buy', - tick: Tick.fromPrice('1.0005'), - flipTick: Tick.fromPrice('1.001'), - }, - ) - expect(receipt1.status).toBe('success') - - // Invalid: flipTick <= tick for bid should fail - await expect( - Actions.dex.placeFlipSync(clientWithAccount, { - token: base, - amount: parseUnits('10', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - flipTick: Tick.fromPrice('1.001'), // Equal - }), - ).rejects.toThrow('The contract function "placeFlip" reverted') - - await expect( - Actions.dex.placeFlipSync(clientWithAccount, { - token: base, - amount: parseUnits('10', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - flipTick: Tick.fromPrice('1.0005'), // Less than - }), - ).rejects.toThrow('The contract function "placeFlip" reverted') - }) - - test('behavior: flip ask requires flipTick < tick', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - // Valid: flipTick < tick for ask - const { receipt: receipt1 } = await Actions.dex.placeFlipSync( - clientWithAccount, - { - token: base, - amount: parseUnits('10', 6), - type: 'sell', - tick: Tick.fromPrice('1.001'), - flipTick: Tick.fromPrice('1.0005'), - }, - ) - expect(receipt1.status).toBe('success') - - // Invalid: flipTick >= tick for ask should fail - await expect( - Actions.dex.placeFlipSync(clientWithAccount, { - token: base, - amount: parseUnits('10', 6), - type: 'sell', - tick: Tick.fromPrice('1.0005'), - flipTick: Tick.fromPrice('1.0005'), // Equal - }), - ).rejects.toThrow('The contract function "placeFlip" reverted') - - await expect( - Actions.dex.placeFlipSync(clientWithAccount, { - token: base, - amount: parseUnits('10', 6), - type: 'sell', - tick: Tick.fromPrice('1.0005'), - flipTick: Tick.fromPrice('1.001'), // Greater than - }), - ).rejects.toThrow('The contract function "placeFlip" reverted') - }) - - test('behavior: flip ticks at boundaries', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - // Flip order with ticks at extreme boundaries - const { receipt } = await Actions.dex.placeFlipSync(clientWithAccount, { - token: base, - amount: parseUnits('10', 6), - type: 'buy', - tick: Tick.minTick, - flipTick: Tick.maxTick, - }) - expect(receipt.status).toBe('success') - }) -}) - -describe('sell', () => { - test('default', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Place bid order to create liquidity - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('500', 6), - type: 'buy', - tick: Tick.fromPrice('0.999'), - }) - - // Sell base tokens - const { receipt } = await Actions.dex.sellSync(clientWithAccount, { - tokenIn: base, - tokenOut: quote, - amountIn: parseUnits('100', 6), - minAmountOut: parseUnits('50', 6), - }) - - expect(receipt).toBeDefined() - expect(receipt.status).toBe('success') - }) - - test('behavior: respects minAmountOut', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Place bid order at low price - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('500', 6), - type: 'buy', - tick: Tick.fromPrice('0.99'), // 1% below peg - }) - - // Try to sell with too high minAmountOut - should fail - await expect( - Actions.dex.sellSync(clientWithAccount, { - tokenIn: base, - tokenOut: quote, - amountIn: parseUnits('100', 6), - minAmountOut: parseUnits('150', 6), // Way too high - }), - ).rejects.toThrow('The contract function "swapExactAmountIn" reverted') - }) - - test('behavior: fails with insufficient liquidity', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // No orders - no liquidity - - // Try to sell - should fail - await expect( - Actions.dex.sellSync(clientWithAccount, { - tokenIn: base, - tokenOut: quote, - amountIn: parseUnits('100', 6), - minAmountOut: parseUnits('50', 6), - }), - ).rejects.toThrow('The contract function "swapExactAmountIn" reverted') - }) -}) - -describe('watchFlipOrderPlaced', () => { - test('default', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - const receivedOrders: Array<{ - args: Actions.dex.watchFlipOrderPlaced.Args - log: Actions.dex.watchFlipOrderPlaced.Log - }> = [] - - const unwatch = Actions.dex.watchFlipOrderPlaced(clientWithAccount, { - onFlipOrderPlaced: (args, log) => { - receivedOrders.push({ args, log }) - }, - }) - - try { - // Place flip order - await Actions.dex.placeFlipSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - flipTick: Tick.fromPrice('1.002'), - }) - - await new Promise((resolve) => setTimeout(resolve, 200)) - - expect(receivedOrders).toHaveLength(1) - expect(receivedOrders[0]?.args.flipTick).toBe(Tick.fromPrice('1.002')) - expect(receivedOrders[0]?.args.tick).toBe(Tick.fromPrice('1.001')) - } finally { - unwatch() - } - }) -}) - -describe('watchOrderCancelled', () => { - test('default', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - const receivedCancellations: Array<{ - args: Actions.dex.watchOrderCancelled.Args - log: Actions.dex.watchOrderCancelled.Log - }> = [] - - const unwatch = Actions.dex.watchOrderCancelled(clientWithAccount, { - onOrderCancelled: (args, log) => { - receivedCancellations.push({ args, log }) - }, - }) - - try { - // Place order - const { orderId } = await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }) - - // Cancel order - await Actions.dex.cancelSync(clientWithAccount, { - orderId, - }) - - await new Promise((resolve) => setTimeout(resolve, 200)) - - expect(receivedCancellations).toHaveLength(1) - expect(receivedCancellations[0]?.args.orderId).toBe(orderId) - } finally { - unwatch() - } - }) - - test('behavior: filter by orderId', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - // Place two orders - const { orderId: orderId1 } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }, - ) - - const { orderId: orderId2 } = await Actions.dex.placeSync( - clientWithAccount, - { - token: base, - amount: parseUnits('50', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }, - ) - - const receivedCancellations: Array<{ - args: Actions.dex.watchOrderCancelled.Args - log: Actions.dex.watchOrderCancelled.Log - }> = [] - - // Watch only for cancellation of orderId1 - const unwatch = Actions.dex.watchOrderCancelled(clientWithAccount, { - orderId: orderId1, - onOrderCancelled: (args, log) => { - receivedCancellations.push({ args, log }) - }, - }) - - try { - // Cancel orderId1 (should be captured) - await Actions.dex.cancelSync(clientWithAccount, { - orderId: orderId1, - }) - - // Cancel orderId2 (should NOT be captured) - await Actions.dex.cancelSync(clientWithAccount, { - orderId: orderId2, - }) - - await new Promise((resolve) => setTimeout(resolve, 200)) - - // Should only receive 1 event - expect(receivedCancellations).toHaveLength(1) - expect(receivedCancellations[0]?.args.orderId).toBe(orderId1) - } finally { - unwatch() - } - }) -}) - -describe.todo('watchOrderFilled') - -describe('watchOrderPlaced', () => { - test('default', async () => { - const { base } = await setupTokenPair(clientWithAccount) - - const receivedOrders: Array<{ - args: Actions.dex.watchOrderPlaced.Args - log: Actions.dex.watchOrderPlaced.Log - }> = [] - - const unwatch = Actions.dex.watchOrderPlaced(clientWithAccount, { - onOrderPlaced: (args, log) => { - receivedOrders.push({ args, log }) - }, - }) - - try { - // Place first order - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }) - - // Place second order - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('50', 6), - type: 'sell', - tick: Tick.fromPrice('0.999'), - }) - - // Wait for events - await new Promise((resolve) => setTimeout(resolve, 200)) - - expect(receivedOrders).toHaveLength(2) - expect(receivedOrders[0]?.args.isBid).toBe(true) - expect(receivedOrders[0]?.args.amount).toBe(parseUnits('100', 6)) - expect(receivedOrders[1]?.args.isBid).toBe(false) - expect(receivedOrders[1]?.args.amount).toBe(parseUnits('50', 6)) - } finally { - unwatch() - } - }) - - test('behavior: filter by token', async () => { - const { base } = await setupTokenPair(clientWithAccount) - const { base: base2 } = await setupTokenPair(clientWithAccount) - - const receivedOrders: Array<{ - args: Actions.dex.watchOrderPlaced.Args - log: Actions.dex.watchOrderPlaced.Log - }> = [] - - // Watch only for orders on base - const unwatch = Actions.dex.watchOrderPlaced(clientWithAccount, { - token: base, - onOrderPlaced: (args, log) => { - receivedOrders.push({ args, log }) - }, - }) - - try { - // Place order on base (should be captured) - await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }) - - // Place order on base2 (should NOT be captured) - await Actions.dex.placeSync(clientWithAccount, { - token: base2, - amount: parseUnits('50', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }) - - await new Promise((resolve) => setTimeout(resolve, 200)) - - // Should only receive 1 event - expect(receivedOrders).toHaveLength(1) - expect(receivedOrders[0]?.args.token.toLowerCase()).toBe( - base.toLowerCase(), - ) - } finally { - unwatch() - } - }) -}) - -describe('withdraw', () => { - test('default', async () => { - const { base, quote } = await setupTokenPair(clientWithAccount) - - // Create internal balance - const { orderId } = await Actions.dex.placeSync(clientWithAccount, { - token: base, - amount: parseUnits('100', 6), - type: 'buy', - tick: Tick.fromPrice('1.001'), - }) - - await Actions.dex.cancelSync(clientWithAccount, { orderId }) - - // Get DEX balance - const dexBalance = await Actions.dex.getBalance(clientWithAccount, { - account: clientWithAccount.account.address, - token: quote, - }) - expect(dexBalance).toBeGreaterThan(0n) - - // Get wallet balance before withdraw - const walletBalanceBefore = await Actions.token.getBalance( - clientWithAccount, - { - token: quote, - }, - ) - - // Withdraw from DEX - const { receipt } = await Actions.dex.withdrawSync(clientWithAccount, { - token: quote, - amount: dexBalance, - }) - - expect(receipt).toBeDefined() - expect(receipt.status).toBe('success') - - // Check DEX balance is now 0 - const dexBalanceAfter = await Actions.dex.getBalance(clientWithAccount, { - account: clientWithAccount.account.address, - token: quote, - }) - expect(dexBalanceAfter).toBe(0n) - - // Check wallet balance increased - const walletBalanceAfter = await Actions.token.getBalance( - clientWithAccount, - { - token: quote, - }, - ) - expect(walletBalanceAfter).toBeGreaterThan(walletBalanceBefore) - }) -}) diff --git a/src/viem/Actions/dex.ts b/src/viem/Actions/dex.ts deleted file mode 100644 index a476e6a7..00000000 --- a/src/viem/Actions/dex.ts +++ /dev/null @@ -1,2150 +0,0 @@ -import * as Hash from 'ox/Hash' -import * as Hex from 'ox/Hex' -import { - type Account, - type Address, - type BaseErrorType, - type Chain, - type Client, - type ExtractAbiItem, - type GetEventArgs, - type Log, - parseEventLogs, - type ReadContractReturnType, - type TransactionReceipt, - type Transport, - type Log as viem_Log, - type WatchContractEventParameters, - type WriteContractReturnType, -} from 'viem' -import { parseAccount } from 'viem/accounts' -import { - readContract, - watchContractEvent, - writeContract, - writeContractSync, -} from 'viem/actions' -import type { Compute, UnionOmit } from '../../internal/types.js' -import * as Abis from '../Abis.js' -import * as Addresses from '../Addresses.js' -import type { - GetAccountParameter, - ReadParameters, - WriteParameters, -} from '../internal/types.js' -import { defineCall } from '../internal/utils.js' - -/** - * Order type for limit orders. - */ -type OrderType = 'buy' | 'sell' - -/** - * Buys a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http, parseUnits } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.dex.buy(client, { - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * amountOut: parseUnits('100', 6), - * maxAmountIn: parseUnits('105', 6), - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function buy< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: buy.Parameters, -): Promise { - return buy.inner(writeContract, client, parameters) -} - -export namespace buy { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount of tokenOut to buy. */ - amountOut: bigint - /** Maximum amount of tokenIn to spend. */ - maxAmountIn: bigint - /** Address of the token to spend. */ - tokenIn: Address - /** Address of the token to buy. */ - tokenOut: Address - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: buy.Parameters, - ): Promise> { - const { tokenIn, tokenOut, amountOut, maxAmountIn, ...rest } = parameters - const call = buy.call({ tokenIn, tokenOut, amountOut, maxAmountIn }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `swapExactAmountOut` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, parseUnits, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * Actions.dex.buy.call({ - * tokenIn: '0x20c0...beef', - * tokenOut: '0x20c0...babe', - * amountOut: parseUnits('100', 6), - * maxAmountIn: parseUnits('105', 6), - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { tokenIn, tokenOut, amountOut, maxAmountIn } = args - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - functionName: 'swapExactAmountOut', - args: [tokenIn, tokenOut, amountOut, maxAmountIn], - }) - } -} - -/** - * Buys a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http, parseUnits } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.dex.buySync(client, { - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * amountOut: parseUnits('100', 6), - * maxAmountIn: parseUnits('105', 6), - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt. - */ -export async function buySync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: buySync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await buy.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - return { receipt } -} - -export namespace buySync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = buy.Parameters - - export type Args = buy.Args - - export type ReturnValue = Compute<{ - /** Transaction receipt. */ - receipt: TransactionReceipt - }> - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Cancels an order from the orderbook. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.dex.cancel(client, { - * orderId: 123n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function cancel< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: cancel.Parameters, -): Promise { - return cancel.inner(writeContract, client, parameters) -} - -export namespace cancel { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Order ID to cancel. */ - orderId: bigint - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: cancel.Parameters, - ): Promise> { - const { orderId, ...rest } = parameters - const call = cancel.call({ orderId }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `cancel` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * Actions.dex.cancel.call({ - * orderId: 123n, - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { orderId } = args - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - functionName: 'cancel', - args: [orderId], - }) - } - - /** - * Extracts the `OrderCancelled` event from logs. - * - * @param logs - The logs. - * @returns The `OrderCancelled` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.stablecoinExchange, - logs, - eventName: 'OrderCancelled', - strict: true, - }) - if (!log) throw new Error('`OrderCancelled` event not found.') - return log - } -} - -/** - * Cancels an order from the orderbook. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.dex.cancelSync(client, { - * orderId: 123n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function cancelSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: cancelSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await cancel.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = cancel.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace cancelSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = cancel.Parameters - - export type Args = cancel.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.stablecoinExchange, - 'OrderCancelled', - { IndexedOnly: false; Required: true } - > & { - /** Transaction receipt. */ - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Creates a new trading pair on the DEX. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.dex.createPair(client, { - * base: '0x20c...11', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function createPair< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: createPair.Parameters, -): Promise { - return createPair.inner(writeContract, client, parameters) -} - -export namespace createPair { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Address of the base token for the pair. */ - base: Address - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: createPair.Parameters, - ): Promise> { - const { base, ...rest } = parameters - const call = createPair.call({ base }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `createPair` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * Actions.dex.createPair.call({ - * base: '0x20c0...beef', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { base } = args - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - functionName: 'createPair', - args: [base], - }) - } - - /** - * Extracts the `PairCreated` event from logs. - * - * @param logs - The logs. - * @returns The `PairCreated` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.stablecoinExchange, - logs, - eventName: 'PairCreated', - strict: true, - }) - if (!log) throw new Error('`PairCreated` event not found.') - return log - } -} - -/** - * Creates a new trading pair on the DEX. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.dex.createPairSync(client, { - * base: '0x20c...11', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function createPairSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: createPairSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await createPair.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = createPair.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace createPairSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = createPair.Parameters - - export type Args = createPair.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.stablecoinExchange, - 'PairCreated', - { IndexedOnly: false; Required: true } - > & { - /** Transaction receipt. */ - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Gets a user's token balance on the DEX. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const balance = await Actions.dex.getBalance(client, { - * account: '0x...', - * token: '0x20c...11', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The user's token balance on the DEX. - */ -export async function getBalance< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: getBalance.Parameters, -): Promise { - const { account: acc = client.account, token, ...rest } = parameters - const address = acc ? parseAccount(acc).address : undefined - if (!address) throw new Error('account is required.') - return readContract(client, { - ...rest, - ...getBalance.call({ account: address, token }), - }) -} - -export namespace getBalance { - export type Parameters< - account extends Account | undefined = Account | undefined, - > = ReadParameters & GetAccountParameter & Args - - export type Args = { - /** Address of the account. */ - account: Address - /** Address of the token. */ - token: Address - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.stablecoinExchange, - 'balanceOf', - never - > - - /** - * Defines a call to the `balanceOf` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { account, token } = args - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - args: [account, token], - functionName: 'balanceOf', - }) - } -} - -/** - * Gets the quote for buying a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http, parseUnits } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const amountIn = await Actions.dex.getBuyQuote(client, { - * amountOut: parseUnits('100', 6), - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The amount of tokenIn needed to buy the specified amountOut. - */ -export async function getBuyQuote( - client: Client, - parameters: getBuyQuote.Parameters, -): Promise { - const { tokenIn, tokenOut, amountOut, ...rest } = parameters - return readContract(client, { - ...rest, - ...getBuyQuote.call({ tokenIn, tokenOut, amountOut }), - }) -} - -export namespace getBuyQuote { - export type Parameters = ReadParameters & Args - - export type Args = { - /** Amount of tokenOut to buy. */ - amountOut: bigint - /** Address of the token to spend. */ - tokenIn: Address - /** Address of the token to buy. */ - tokenOut: Address - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.stablecoinExchange, - 'quoteSwapExactAmountOut', - never - > - - /** - * Defines a call to the `quoteSwapExactAmountOut` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { tokenIn, tokenOut, amountOut } = args - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - args: [tokenIn, tokenOut, amountOut], - functionName: 'quoteSwapExactAmountOut', - }) - } -} - -/** - * Gets an order's details from the orderbook. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const order = await Actions.dex.getOrder(client, { - * orderId: 123n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The order details. - */ -export async function getOrder( - client: Client, - parameters: getOrder.Parameters, -): Promise { - const { orderId, ...rest } = parameters - return readContract(client, { - ...rest, - ...getOrder.call({ orderId }), - }) -} - -export namespace getOrder { - export type Parameters = ReadParameters & Args - - export type Args = { - /** Order ID to query. */ - orderId: bigint - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.stablecoinExchange, - 'getOrder', - never - > - - /** - * Defines a call to the `getOrder` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { orderId } = args - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - args: [orderId], - functionName: 'getOrder', - }) - } -} - -/** - * Gets orderbook information for a trading pair. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const book = await Actions.dex.getOrderbook(client, { - * base: '0x20c...11', - * quote: '0x20c...20', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The orderbook information. - */ -export async function getOrderbook( - client: Client, - parameters: getOrderbook.Parameters, -): Promise { - const { base, quote, ...rest } = parameters - return readContract(client, { - ...rest, - ...getOrderbook.call({ base, quote }), - }) -} - -export namespace getOrderbook { - export type Parameters = ReadParameters & Args - - export type Args = { - /** Address of the base token. */ - base: Address - /** Address of the quote token. */ - quote: Address - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.stablecoinExchange, - 'books', - never - > - - /** - * Defines a call to the `books` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { base, quote } = args - const pairKey = getPairKey(base, quote) - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - args: [pairKey], - functionName: 'books', - }) - } -} - -/** - * Gets the price level information at a specific tick. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const level = await Actions.dex.getTickLevel(client, { - * base: '0x20c...11', - * tick: Tick.fromPrice('1.001'), - * isBid: true, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The price level information. - */ -export async function getTickLevel( - client: Client, - parameters: getTickLevel.Parameters, -): Promise { - const { base, tick, isBid, ...rest } = parameters - const [head, tail, totalLiquidity] = await readContract(client, { - ...rest, - ...getTickLevel.call({ base, tick, isBid }), - }) - return { head, tail, totalLiquidity } -} - -export namespace getTickLevel { - export type Parameters = ReadParameters & Args - - export type Args = { - /** Address of the base token. */ - base: Address - /** Whether to query the bid side (true) or ask side (false). */ - isBid: boolean - /** Price tick to query. */ - tick: number - } - - export type ReturnValue = { - /** Order ID of the first order at this tick (0 if empty) */ - head: bigint - /** Order ID of the last order at this tick (0 if empty) */ - tail: bigint - /** Total liquidity available at this tick level */ - totalLiquidity: bigint - } - - /** - * Defines a call to the `getTickLevel` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { base, tick, isBid } = args - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - args: [base, tick, isBid], - functionName: 'getTickLevel', - }) - } -} - -/** - * Gets the quote for selling a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http, parseUnits } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const amountOut = await Actions.dex.getSellQuote(client, { - * amountIn: parseUnits('100', 6), - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The amount of tokenOut received for selling the specified amountIn. - */ -export async function getSellQuote( - client: Client, - parameters: getSellQuote.Parameters, -): Promise { - const { tokenIn, tokenOut, amountIn, ...rest } = parameters - return readContract(client, { - ...rest, - ...getSellQuote.call({ tokenIn, tokenOut, amountIn }), - }) -} - -export namespace getSellQuote { - export type Parameters = ReadParameters & Args - - export type Args = { - /** Amount of tokenIn to sell. */ - amountIn: bigint - /** Address of the token to sell. */ - tokenIn: Address - /** Address of the token to receive. */ - tokenOut: Address - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.stablecoinExchange, - 'quoteSwapExactAmountIn', - never - > - - /** - * Defines a call to the `quoteSwapExactAmountIn` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { tokenIn, tokenOut, amountIn } = args - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - args: [tokenIn, tokenOut, amountIn], - functionName: 'quoteSwapExactAmountIn', - }) - } -} - -/** - * Places a limit order on the orderbook. - * - * @example - * ```ts - * import { createClient, http, parseUnits } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.dex.place(client, { - * amount: parseUnits('100', 6), - * tick: Tick.fromPrice('0.99'), - * token: '0x20c...11', - * type: 'buy', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function place< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: place.Parameters, -): Promise { - return place.inner(writeContract, client, parameters) -} - -export namespace place { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount of tokens to place in the order. */ - amount: bigint - /** Price tick for the order. */ - tick: number - /** Address of the base token. */ - token: Address - /** Order type - 'buy' to buy the token, 'sell' to sell it. */ - type: OrderType - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: place.Parameters, - ): Promise> { - const { amount, token, type, tick, ...rest } = parameters - const call = place.call({ amount, token, type, tick }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `place` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, parseUnits, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * Actions.dex.place.call({ - * amount: parseUnits('100', 6), - * tick: Tick.fromPrice('0.99'), - * token: '0x20c0...beef', - * type: 'buy', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token, amount, type, tick } = args - const isBid = type === 'buy' - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - functionName: 'place', - args: [token, amount, isBid, tick], - }) - } - - /** - * Extracts the `OrderPlaced` event from logs. - * - * @param logs - The logs. - * @returns The `OrderPlaced` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.stablecoinExchange, - logs, - eventName: 'OrderPlaced', - strict: true, - }) - if (!log) throw new Error('`OrderPlaced` event not found.') - return log - } -} - -/** - * Places a flip order that automatically flips when filled. - * - * @example - * ```ts - * import { createClient, http, parseUnits } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.dex.placeFlip(client, { - * amount: parseUnits('100', 6), - * flipTick: Tick.fromPrice('1.01'), - * tick: Tick.fromPrice('0.99'), - * token: '0x20c...11', - * type: 'buy', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function placeFlip< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: placeFlip.Parameters, -): Promise { - return placeFlip.inner(writeContract, client, parameters) -} - -export namespace placeFlip { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount of tokens to place in the order. */ - amount: bigint - /** Target tick to flip to when order is filled. */ - flipTick: number - /** Price tick for the order. */ - tick: number - /** Address of the base token. */ - token: Address - /** Order type - 'buy' to buy the token, 'sell' to sell it. */ - type: OrderType - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: placeFlip.Parameters, - ): Promise> { - const { amount, flipTick, tick, token, type, ...rest } = parameters - const call = placeFlip.call({ amount, flipTick, tick, token, type }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `placeFlip` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, parseUnits, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * Actions.dex.placeFlip.call({ - * amount: parseUnits('100', 6), - * flipTick: Tick.fromPrice('1.01'), - * tick: Tick.fromPrice('0.99'), - * token: '0x20c0...beef', - * type: 'buy', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token, amount, type, tick, flipTick } = args - const isBid = type === 'buy' - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - functionName: 'placeFlip', - args: [token, amount, isBid, tick, flipTick], - }) - } - - /** - * Extracts the `FlipOrderPlaced` event from logs. - * - * @param logs - The logs. - * @returns The `FlipOrderPlaced` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.stablecoinExchange, - logs, - eventName: 'FlipOrderPlaced', - strict: true, - }) - if (!log) throw new Error('`FlipOrderPlaced` event not found.') - return log - } -} - -/** - * Places a flip order that automatically flips when filled. - * - * @example - * ```ts - * import { createClient, http, parseUnits } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.dex.placeFlipSync(client, { - * amount: parseUnits('100', 6), - * flipTick: Tick.fromPrice('1.01'), - * tick: Tick.fromPrice('0.99'), - * token: '0x20c...11', - * type: 'buy', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function placeFlipSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: placeFlipSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await placeFlip.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = placeFlip.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace placeFlipSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = placeFlip.Parameters - - export type Args = placeFlip.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.stablecoinExchange, - 'FlipOrderPlaced', - { IndexedOnly: false; Required: true } - > & { - /** Transaction receipt. */ - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Places a limit order on the orderbook. - * - * @example - * ```ts - * import { createClient, http, parseUnits } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.dex.placeSync(client, { - * amount: parseUnits('100', 6), - * tick: Tick.fromPrice('0.99'), - * token: '0x20c...11', - * type: 'buy', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function placeSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: placeSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await place.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = place.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace placeSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = place.Parameters - - export type Args = place.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.stablecoinExchange, - 'OrderPlaced', - { IndexedOnly: false; Required: true } - > & { - /** Transaction receipt. */ - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Sells a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http, parseUnits } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.dex.sell(client, { - * amountIn: parseUnits('100', 6), - * minAmountOut: parseUnits('95', 6), - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function sell< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: sell.Parameters, -): Promise { - return sell.inner(writeContract, client, parameters) -} - -export namespace sell { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount of tokenIn to sell. */ - amountIn: bigint - /** Minimum amount of tokenOut to receive. */ - minAmountOut: bigint - /** Address of the token to sell. */ - tokenIn: Address - /** Address of the token to receive. */ - tokenOut: Address - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: sell.Parameters, - ): Promise> { - const { tokenIn, tokenOut, amountIn, minAmountOut, ...rest } = parameters - const call = sell.call({ tokenIn, tokenOut, amountIn, minAmountOut }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `swapExactAmountIn` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, parseUnits, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * Actions.dex.sell.call({ - * amountIn: parseUnits('100', 6), - * minAmountOut: parseUnits('95', 6), - * tokenIn: '0x20c0...beef', - * tokenOut: '0x20c0...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { tokenIn, tokenOut, amountIn, minAmountOut } = args - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - functionName: 'swapExactAmountIn', - args: [tokenIn, tokenOut, amountIn, minAmountOut], - }) - } -} - -/** - * Sells a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http, parseUnits } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.dex.sellSync(client, { - * amountIn: parseUnits('100', 6), - * minAmountOut: parseUnits('95', 6), - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt. - */ -export async function sellSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: sellSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await sell.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - return { receipt } -} - -export namespace sellSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = sell.Parameters - - export type Args = sell.Args - - export type ReturnValue = Compute<{ - /** Transaction receipt. */ - receipt: TransactionReceipt - }> - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Watches for flip order placed events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = Actions.dex.watchFlipOrderPlaced(client, { - * onFlipOrderPlaced: (args, log) => { - * console.log('Flip order placed:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchFlipOrderPlaced< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchFlipOrderPlaced.Parameters, -) { - const { onFlipOrderPlaced, maker, token, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - eventName: 'FlipOrderPlaced', - args: { - ...(maker !== undefined && { maker }), - ...(token !== undefined && { token }), - }, - onLogs: (logs) => { - for (const log of logs) onFlipOrderPlaced(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchFlipOrderPlaced { - export type Args = GetEventArgs< - typeof Abis.stablecoinExchange, - 'FlipOrderPlaced', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters< - typeof Abis.stablecoinExchange, - 'FlipOrderPlaced', - true - >, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Address of the maker to filter events. */ - maker?: Address | undefined - /** Callback to invoke when a flip order is placed. */ - onFlipOrderPlaced: (args: Args, log: Log) => void - /** Address of the token to filter events. */ - token?: Address | undefined - } -} - -/** - * Watches for order cancelled events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = Actions.dex.watchOrderCancelled(client, { - * onOrderCancelled: (args, log) => { - * console.log('Order cancelled:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchOrderCancelled< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchOrderCancelled.Parameters, -) { - const { onOrderCancelled, orderId, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - eventName: 'OrderCancelled', - args: orderId !== undefined ? { orderId } : undefined, - onLogs: (logs) => { - for (const log of logs) onOrderCancelled(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchOrderCancelled { - export type Args = GetEventArgs< - typeof Abis.stablecoinExchange, - 'OrderCancelled', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters< - typeof Abis.stablecoinExchange, - 'OrderCancelled', - true - >, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when an order is cancelled. */ - onOrderCancelled: (args: Args, log: Log) => void - /** Order ID to filter events. */ - orderId?: bigint | undefined - } -} - -/** - * Watches for order filled events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = Actions.dex.watchOrderFilled(client, { - * onOrderFilled: (args, log) => { - * console.log('Order filled:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchOrderFilled< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchOrderFilled.Parameters, -) { - const { onOrderFilled, maker, taker, orderId, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - eventName: 'OrderFilled', - args: { - ...(orderId !== undefined && { orderId }), - ...(maker !== undefined && { maker }), - ...(taker !== undefined && { taker }), - }, - onLogs: (logs) => { - for (const log of logs) onOrderFilled(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchOrderFilled { - export type Args = GetEventArgs< - typeof Abis.stablecoinExchange, - 'OrderFilled', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters< - typeof Abis.stablecoinExchange, - 'OrderFilled', - true - >, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Address of the maker to filter events. */ - maker?: Address | undefined - /** Callback to invoke when an order is filled. */ - onOrderFilled: (args: Args, log: Log) => void - /** Order ID to filter events. */ - orderId?: bigint | undefined - /** Address of the taker to filter events. */ - taker?: Address | undefined - } -} - -/** - * Watches for order placed events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = Actions.dex.watchOrderPlaced(client, { - * onOrderPlaced: (args, log) => { - * console.log('Order placed:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchOrderPlaced< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchOrderPlaced.Parameters, -) { - const { onOrderPlaced, maker, token, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - eventName: 'OrderPlaced', - args: { - ...(maker !== undefined && { maker }), - ...(token !== undefined && { token }), - }, - onLogs: (logs) => { - for (const log of logs) onOrderPlaced(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchOrderPlaced { - export type Args = GetEventArgs< - typeof Abis.stablecoinExchange, - 'OrderPlaced', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters< - typeof Abis.stablecoinExchange, - 'OrderPlaced', - true - >, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Address of the maker to filter events. */ - maker?: Address | undefined - /** Callback to invoke when an order is placed. */ - onOrderPlaced: (args: Args, log: Log) => void - /** Address of the token to filter events. */ - token?: Address | undefined - } -} - -/** - * Withdraws tokens from the DEX to the caller's wallet. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.dex.withdraw(client, { - * amount: 100n, - * token: '0x20c...11', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function withdraw< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: withdraw.Parameters, -): Promise { - return withdraw.inner(writeContract, client, parameters) -} - -export namespace withdraw { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount to withdraw. */ - amount: bigint - /** Address of the token to withdraw. */ - token: Address - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: withdraw.Parameters, - ): Promise> { - const { token, amount, ...rest } = parameters - const call = withdraw.call({ token, amount }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `withdraw` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, parseUnits, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * Actions.dex.withdraw.call({ - * amount: parseUnits('100', 6), - * token: '0x20c0...beef', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token, amount } = args - return defineCall({ - address: Addresses.stablecoinExchange, - abi: Abis.stablecoinExchange, - functionName: 'withdraw', - args: [token, amount], - }) - } -} - -/** - * Withdraws tokens from the DEX to the caller's wallet. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.dex.withdrawSync(client, { - * amount: 100n, - * token: '0x20c...11', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt. - */ -export async function withdrawSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: withdrawSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await withdraw.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - return { receipt } -} - -export namespace withdrawSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = withdraw.Parameters - - export type Args = withdraw.Args - - export type ReturnValue = Compute<{ - /** Transaction receipt. */ - receipt: TransactionReceipt - }> - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -function getPairKey(base: Address, quote: Address) { - const [tokenA, tokenB] = - Hex.toBigInt(base) < Hex.toBigInt(quote) ? [base, quote] : [quote, base] - return Hash.keccak256(Hex.concat(tokenA, tokenB)) -} diff --git a/src/viem/Actions/faucet.ts b/src/viem/Actions/faucet.ts deleted file mode 100644 index 0e81a869..00000000 --- a/src/viem/Actions/faucet.ts +++ /dev/null @@ -1,121 +0,0 @@ -import type { - Account, - Address, - Chain, - Client, - Hash, - TransactionReceipt, - Transport, -} from 'viem' -import { waitForTransactionReceipt } from 'viem/actions' -import { parseAccount } from 'viem/utils' - -/** - * Funds an account with an initial amount of set token(s) - * on Tempo's testnet. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), - * transport: http(), - * }) - * - * const hashes = await Actions.faucet.fund(client, { - * account: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function fund( - client: Client, - parameters: fund.Parameters, -): Promise { - const account = parseAccount(parameters.account) - return client.request<{ - Method: 'tempo_fundAddress' - Parameters: [address: Address] - ReturnType: readonly Hash[] - }>({ - method: 'tempo_fundAddress', - params: [account.address], - }) -} - -export declare namespace fund { - export type Parameters = { - /** Account to fund. */ - account: Account | Address - } - - export type ReturnValue = readonly Hash[] -} - -/** - * Funds an account with an initial amount of set token(s) - * on Tempo's testnet. Waits for the transactions to be included - * on a block before returning a response. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), - * transport: http(), - * }) - * - * const hashes = await Actions.faucet.fundSync(client, { - * account: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function fundSync( - client: Client, - parameters: fundSync.Parameters, -): Promise { - const { timeout = 10_000 } = parameters - const account = parseAccount(parameters.account) - const hashes = await client.request<{ - Method: 'tempo_fundAddress' - Parameters: [address: Address] - ReturnType: readonly Hash[] - }>({ - method: 'tempo_fundAddress', - params: [account.address], - }) - const receipts = await Promise.all( - hashes.map((hash) => - waitForTransactionReceipt(client, { - hash, - checkReplacement: false, - timeout, - }), - ), - ) - return receipts -} - -export declare namespace fundSync { - export type Parameters = { - /** Account to fund. */ - account: Account | Address - /** Timeout. */ - timeout?: number | undefined - } - - export type ReturnValue = readonly TransactionReceipt[] -} diff --git a/src/viem/Actions/fee.test.ts b/src/viem/Actions/fee.test.ts deleted file mode 100644 index 54d90e09..00000000 --- a/src/viem/Actions/fee.test.ts +++ /dev/null @@ -1,259 +0,0 @@ -import { setTimeout } from 'node:timers/promises' -import { Abis } from 'tempo.ts/viem' -import { parseUnits } from 'viem' -import { writeContractSync } from 'viem/actions' -import { afterEach, describe, expect, test } from 'vitest' -import { rpcUrl } from '../../../test/config.js' -import { - accounts, - clientWithAccount, - fundAddress, -} from '../../../test/viem/config.js' -import * as actions from './index.js' - -const account2 = accounts[1] -const account3 = accounts[2] - -afterEach(async () => { - await fetch(`${rpcUrl}/restart`) -}) - -describe('getUserToken', () => { - test('default', async () => { - // Fund accounts - await fundAddress(clientWithAccount, { address: account2.address }) - await fundAddress(clientWithAccount, { address: account3.address }) - - // Set token (address) - await actions.fee.setUserTokenSync(clientWithAccount, { - account: account2, - token: '0x20c0000000000000000000000000000000000001', - }) - - // Set another token (id) - await actions.fee.setUserTokenSync(clientWithAccount, { - account: account3, - token: 2n, - }) - - expect( - await actions.fee.getUserToken(clientWithAccount, { account: account2 }), - ).toMatchInlineSnapshot(` - { - "address": "0x20C0000000000000000000000000000000000001", - "id": 1n, - } - `) - expect( - await actions.fee.getUserToken(clientWithAccount, { account: account3 }), - ).toMatchInlineSnapshot(` - { - "address": "0x20C0000000000000000000000000000000000002", - "id": 2n, - } - `) - }) -}) - -describe('setUserToken', () => { - test('default', async () => { - expect( - await actions.fee.getUserToken(clientWithAccount), - ).toMatchInlineSnapshot( - ` - { - "address": "0x20C0000000000000000000000000000000000001", - "id": 1n, - } - `, - ) - - const { receipt: setReceipt, ...setResult } = - await actions.fee.setUserTokenSync(clientWithAccount, { - token: 2n, - }) - expect(setReceipt).toBeDefined() - expect(setResult).toMatchInlineSnapshot(` - { - "token": "0x20C0000000000000000000000000000000000002", - "user": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - expect( - await actions.fee.getUserToken(clientWithAccount, {}), - ).toMatchInlineSnapshot( - ` - { - "address": "0x20C0000000000000000000000000000000000002", - "id": 2n, - } - `, - ) - - const { receipt: resetReceipt, ...resetResult } = - await actions.fee.setUserTokenSync(clientWithAccount, { - feeToken: 1n, - token: 1n, - }) - expect(resetReceipt).toBeDefined() - expect(resetResult).toMatchInlineSnapshot(` - { - "token": "0x20C0000000000000000000000000000000000001", - "user": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - expect( - await actions.fee.getUserToken(clientWithAccount, {}), - ).toMatchInlineSnapshot( - ` - { - "address": "0x20C0000000000000000000000000000000000001", - "id": 1n, - } - `, - ) - }) -}) - -describe('watchSetUserToken', async () => { - test('default', async () => { - const receivedSets: Array<{ - args: actions.fee.watchSetUserToken.Args - log: actions.fee.watchSetUserToken.Log - }> = [] - - // Start watching for user token set events - const unwatch = actions.fee.watchSetUserToken(clientWithAccount, { - onUserTokenSet: (args, log) => { - receivedSets.push({ args, log }) - }, - }) - - try { - // Set token for account2 - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: '0x20c0000000000000000000000000000000000001', - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - await actions.fee.setUserTokenSync(clientWithAccount, { - account: account2, - token: '0x20c0000000000000000000000000000000000001', - }) - - // Set token for account3 - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: '0x20c0000000000000000000000000000000000001', - functionName: 'transfer', - args: [account3.address, parseUnits('1', 6)], - }) - - await actions.fee.setUserTokenSync(clientWithAccount, { - account: account3, - token: '0x20c0000000000000000000000000000000000002', - }) - - await setTimeout(500) - - expect(receivedSets).toHaveLength(2) - - expect(receivedSets.at(0)!.args).toMatchInlineSnapshot(` - { - "token": "0x20C0000000000000000000000000000000000001", - "user": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - expect(receivedSets.at(1)!.args).toMatchInlineSnapshot(` - { - "token": "0x20C0000000000000000000000000000000000002", - "user": "0x98e503f35D0a019cB0a251aD243a4cCFCF371F46", - } - `) - } finally { - if (unwatch) unwatch() - } - }) - - test('behavior: filter by user address', async () => { - const receivedSets: Array<{ - args: actions.fee.watchSetUserToken.Args - log: actions.fee.watchSetUserToken.Log - }> = [] - - // Start watching for user token set events only for account2 - const unwatch = actions.fee.watchSetUserToken(clientWithAccount, { - args: { - user: account2.address, - }, - onUserTokenSet: (args, log) => { - receivedSets.push({ args, log }) - }, - }) - - try { - // Transfer gas to accounts - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: '0x20c0000000000000000000000000000000000001', - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: '0x20c0000000000000000000000000000000000001', - functionName: 'transfer', - args: [account3.address, parseUnits('1', 6)], - }) - - // Set token for account2 (should be captured) - await actions.fee.setUserTokenSync(clientWithAccount, { - account: account2, - token: '0x20c0000000000000000000000000000000000001', - }) - - // Set token for account3 (should NOT be captured) - await actions.fee.setUserTokenSync(clientWithAccount, { - account: account3, - token: '0x20c0000000000000000000000000000000000002', - }) - - // Set token for account2 again (should be captured) - await actions.fee.setUserTokenSync(clientWithAccount, { - account: account2, - feeToken: 1n, - token: 2n, - }) - - await setTimeout(500) - - // Should only receive 2 events (for account2) - expect(receivedSets).toHaveLength(2) - - expect(receivedSets.at(0)!.args).toMatchInlineSnapshot(` - { - "token": "0x20C0000000000000000000000000000000000001", - "user": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - expect(receivedSets.at(1)!.args).toMatchInlineSnapshot(` - { - "token": "0x20C0000000000000000000000000000000000002", - "user": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - - // Verify all received events are for account2 - for (const set of receivedSets) { - expect(set.args.user).toBe(account2.address) - } - } finally { - if (unwatch) unwatch() - } - }) -}) diff --git a/src/viem/Actions/fee.ts b/src/viem/Actions/fee.ts deleted file mode 100644 index 35915ea7..00000000 --- a/src/viem/Actions/fee.ts +++ /dev/null @@ -1,372 +0,0 @@ -import { TokenId } from 'ox/tempo' -import { - type Account, - type Address, - type BaseErrorType, - type Chain, - type Client, - type ExtractAbiItem, - type GetEventArgs, - type Log, - parseEventLogs, - type TransactionReceipt, - type Transport, - type Log as viem_Log, - type WatchContractEventParameters, - type WriteContractReturnType, - zeroAddress, -} from 'viem' -import { parseAccount } from 'viem/accounts' -import { - readContract, - watchContractEvent, - writeContract, - writeContractSync, -} from 'viem/actions' -import type { Compute, UnionOmit } from '../../internal/types.js' -import * as Abis from '../Abis.js' -import * as Addresses from '../Addresses.js' -import type { - GetAccountParameter, - ReadParameters, - WriteParameters, -} from '../internal/types.js' -import { defineCall } from '../internal/utils.js' - -/** - * Gets the user's default fee token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const { address, id } = await Actions.fee.getUserToken(client) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function getUserToken< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - ...parameters: account extends Account - ? [getUserToken.Parameters] | [] - : [getUserToken.Parameters] -): Promise { - const { account: account_ = client.account, ...rest } = parameters[0] ?? {} - if (!account_) throw new Error('account is required.') - const account = parseAccount(account_) - const address = await readContract(client, { - ...rest, - ...getUserToken.call({ account: account.address }), - }) - if (address === zeroAddress) return null - return { - address, - id: TokenId.fromAddress(address), - } -} - -export namespace getUserToken { - export type Parameters< - account extends Account | undefined = Account | undefined, - > = ReadParameters & GetAccountParameter - - export type Args = { - /** Account address. */ - account: Address - } - - export type ReturnValue = Compute<{ - address: Address - id: bigint - } | null> - - /** - * Defines a call to the `userTokens` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { account } = args - return defineCall({ - address: Addresses.feeManager, - abi: Abis.feeManager, - args: [account], - functionName: 'userTokens', - }) - } -} - -/** - * Sets the user's default fee token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.fee.setUserToken(client, { - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function setUserToken< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: setUserToken.Parameters, -): Promise { - return setUserToken.inner(writeContract, client, parameters) -} - -export namespace setUserToken { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: setUserToken.Parameters, - ): Promise> { - const { token, ...rest } = parameters - const call = setUserToken.call({ token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `setUserToken` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.fee.setUserToken.call({ - * token: '0x20c0...beef', - * }), - * actions.fee.setUserToken.call({ - * token: '0x20c0...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token } = args - return defineCall({ - address: Addresses.feeManager, - abi: Abis.feeManager, - functionName: 'setUserToken', - args: [TokenId.toAddress(token)], - }) - } - - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.feeManager, - logs, - eventName: 'UserTokenSet', - strict: true, - }) - if (!log) throw new Error('`UserTokenSet` event not found.') - return log - } -} - -/** - * Sets the user's default fee token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.fee.setUserTokenSync(client, { - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function setUserTokenSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: setUserTokenSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await setUserToken.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = setUserToken.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace setUserTokenSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = setUserToken.Parameters - - export type Args = setUserToken.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.feeManager, - 'UserTokenSet', - { IndexedOnly: false; Required: true } - > & { - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Watches for user token set events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.fee.watchSetUserToken(client, { - * onUserTokenSet: (args, log) => { - * console.log('User token set:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchSetUserToken< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchSetUserToken.Parameters, -) { - const { onUserTokenSet, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.feeManager, - abi: Abis.feeManager, - eventName: 'UserTokenSet', - onLogs: (logs) => { - for (const log of logs) onUserTokenSet(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchSetUserToken { - export type Args = GetEventArgs< - typeof Abis.feeManager, - 'UserTokenSet', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a user token is set. */ - onUserTokenSet: (args: Args, log: Log) => void - } -} diff --git a/src/viem/Actions/index.ts b/src/viem/Actions/index.ts deleted file mode 100644 index 7fadbac2..00000000 --- a/src/viem/Actions/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export { verifyHash } from './account.js' -export * as amm from './amm.js' -export * as dex from './dex.js' -export * as faucet from './faucet.js' -export * as fee from './fee.js' -export * as nonce from './nonce.js' -export * as policy from './policy.js' -export * as reward from './reward.js' -export * as token from './token.js' diff --git a/src/viem/Actions/nonce.test.ts b/src/viem/Actions/nonce.test.ts deleted file mode 100644 index 3f32c327..00000000 --- a/src/viem/Actions/nonce.test.ts +++ /dev/null @@ -1,206 +0,0 @@ -import { setTimeout } from 'node:timers/promises' -import { beforeEach, describe, expect, test } from 'vitest' -import { rpcUrl } from '../../../test/config.js' -import { accounts, clientWithAccount } from '../../../test/viem/config.js' -import * as actions from './index.js' - -const account = accounts[0] -const account2 = accounts[1] - -beforeEach(async () => { - await fetch(`${rpcUrl}/restart`) -}) - -describe('getNonce', () => { - test('default', async () => { - // Get nonce for an account with previously unused noncekey - const nonce = await actions.nonce.getNonce(clientWithAccount, { - account: account.address, - nonceKey: 1n, - }) - - expect(nonce).toBe(0n) - }) - - test('behavior: different nonce keys are independent', async () => { - let nonce1 = await actions.nonce.getNonce(clientWithAccount, { - account: account.address, - nonceKey: 1n, - }) - let nonce2 = await actions.nonce.getNonce(clientWithAccount, { - account: account.address, - nonceKey: 2n, - }) - - expect(nonce1).toBe(0n) - expect(nonce2).toBe(0n) - - await actions.token.transferSync(clientWithAccount, { - to: account2.address, - amount: 1n, - token: 1n, - nonceKey: 2n, - }) - - nonce1 = await actions.nonce.getNonce(clientWithAccount, { - account: account.address, - nonceKey: 1n, - }) - nonce2 = await actions.nonce.getNonce(clientWithAccount, { - account: account.address, - nonceKey: 2n, - }) - - // nonceKey 2 should be incremented to 2 - expect(nonce1).toBe(0n) - expect(nonce2).toBe(1n) - }) - - test('behavior: different accounts are independent', async () => { - await actions.token.transferSync(clientWithAccount, { - to: account2.address, - amount: 1n, - token: 1n, - nonceKey: 1n, - }) - const nonce1 = await actions.nonce.getNonce(clientWithAccount, { - account: account.address, - nonceKey: 1n, - }) - const nonce2 = await actions.nonce.getNonce(clientWithAccount, { - account: account2.address, - nonceKey: 1n, - }) - - expect(nonce1).toBe(1n) - expect(nonce2).toBe(0n) - }) -}) - -describe('getNonceKeyCount', () => { - test('default', async () => { - // Get active nonce key count for a fresh account - const count = await actions.nonce.getNonceKeyCount(clientWithAccount, { - account: accounts.at(10)!.address, - }) - - // Fresh account should have 0 active nonce keys - expect(count).toBe(0n) - }) - - test('behavior: different accounts are independent', async () => { - const count1 = await actions.nonce.getNonceKeyCount(clientWithAccount, { - account: accounts.at(10)!.address, - }) - const count2 = await actions.nonce.getNonceKeyCount(clientWithAccount, { - account: accounts.at(11)!.address, - }) - - // Both should be 0 for fresh accounts - expect(count1).toBe(0n) - expect(count2).toBe(0n) - }) -}) - -describe('watchNonceIncremented', () => { - test('default', async () => { - const events: Array<{ - args: actions.nonce.watchNonceIncremented.Args - log: actions.nonce.watchNonceIncremented.Log - }> = [] - - const unwatch = actions.nonce.watchNonceIncremented(clientWithAccount, { - onNonceIncremented: (args, log) => { - events.push({ args, log }) - }, - args: { - account: account.address, - nonceKey: 5n, - }, - }) - - try { - // Have to manually set nonce because eth_FillTransaction does not support nonce keys - await actions.token.transferSync(clientWithAccount, { - to: account2.address, - amount: 1n, - token: 1n, - nonceKey: 5n, - nonce: 0, - }) - - await actions.token.transferSync(clientWithAccount, { - to: account2.address, - amount: 1n, - token: 1n, - nonceKey: 5n, - nonce: 1, - }) - - await setTimeout(1000) - - expect(events).toHaveLength(2) - expect(events[0]!.args.account).toBe(account.address) - expect(events[0]!.args.nonceKey).toBe(5n) - expect(events[0]!.args.newNonce).toBe(1n) - expect(events[1]!.args.newNonce).toBe(2n) - } finally { - unwatch() - } - }) -}) - -describe('watchActiveKeyCountChanged', () => { - test('default', async () => { - const events: Array<{ - args: actions.nonce.watchActiveKeyCountChanged.Args - log: actions.nonce.watchActiveKeyCountChanged.Log - }> = [] - - const unwatch = actions.nonce.watchActiveKeyCountChanged( - clientWithAccount, - { - onActiveKeyCountChanged: (args, log) => { - events.push({ args, log }) - }, - }, - ) - - const priorKeyCount = await actions.nonce.getNonceKeyCount( - clientWithAccount, - { - account: account.address, - }, - ) - - try { - // First use of nonceKey 10 should increment active key count - await actions.token.transferSync(clientWithAccount, { - to: account2.address, - amount: 1n, - token: 1n, - nonceKey: 10n, - nonce: 0, - }) - - // First use of nonceKey 11 should increment again - await actions.token.transferSync(clientWithAccount, { - to: account2.address, - amount: 1n, - token: 1n, - nonceKey: 11n, - nonce: 0, - }) - - await setTimeout(1000) - - expect(events).toHaveLength(2) - expect(events[0]!.args.account).toBe(account.address) - // Assert the number of new active keys - expect(events[0]!.args.newCount - priorKeyCount).toBe(1n) - expect(events[1]!.args.newCount - priorKeyCount).toBe(2n) - } finally { - unwatch() - } - }) -}) diff --git a/src/viem/Actions/nonce.ts b/src/viem/Actions/nonce.ts deleted file mode 100644 index 0eaec735..00000000 --- a/src/viem/Actions/nonce.ts +++ /dev/null @@ -1,347 +0,0 @@ -import type { - Account, - Address, - Chain, - Client, - ExtractAbiItem, - GetEventArgs, - ReadContractReturnType, - Transport, - Log as viem_Log, - WatchContractEventParameters, -} from 'viem' -import { readContract, watchContractEvent } from 'viem/actions' -import type { UnionOmit } from '../../internal/types.js' -import * as Abis from '../Abis.js' -import * as Addresses from '../Addresses.js' -import type { ReadParameters } from '../internal/types.js' -import { defineCall } from '../internal/utils.js' - -/** - * Gets the nonce for an account and nonce key. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), - * transport: http(), - * }) - * - * const nonce = await Actions.nonce.getNonce(client, { - * account: '0x...', - * nonceKey: 1n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The nonce value. - */ -export async function getNonce< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: getNonce.Parameters, -): Promise { - const { account, nonceKey, ...rest } = parameters - return readContract(client, { - ...rest, - ...getNonce.call({ account, nonceKey }), - }) -} - -export namespace getNonce { - export type Parameters = ReadParameters & Args - - export type Args = { - /** Account address. */ - account: Address - /** Nonce key (must be > 0, key 0 is reserved for protocol nonces). */ - nonceKey: bigint - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.nonce, - 'getNonce', - never - > - - /** - * Defines a call to the `getNonce` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`multicall`](https://viem.sh/docs/contract/multicall): execute multiple calls in parallel - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), - * transport: http(), - * }) - * - * const result = await client.multicall({ - * contracts: [ - * Actions.nonce.getNonce.call({ account: '0x...', nonceKey: 1n }), - * Actions.nonce.getNonce.call({ account: '0x...', nonceKey: 2n }), - * ], - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { account, nonceKey } = args - return defineCall({ - address: Addresses.nonceManager, - abi: Abis.nonce, - args: [account, nonceKey], - functionName: 'getNonce', - }) - } -} - -/** - * Gets the number of active nonce keys for an account. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), - * transport: http(), - * }) - * - * const count = await Actions.nonce.getNonceKeyCount(client, { - * account: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The number of active nonce keys. - */ -export async function getNonceKeyCount< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: getNonceKeyCount.Parameters, -): Promise { - const { account, ...rest } = parameters - return readContract(client, { - ...rest, - ...getNonceKeyCount.call({ account }), - }) -} - -export namespace getNonceKeyCount { - export type Parameters = ReadParameters & Args - - export type Args = { - /** Account address. */ - account: Address - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.nonce, - 'getActiveNonceKeyCount', - never - > - - /** - * Defines a call to the `getNonceKeyCount` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`multicall`](https://viem.sh/docs/contract/multicall): execute multiple calls in parallel - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), - * transport: http(), - * }) - * - * const result = await client.multicall({ - * contracts: [ - * Actions.nonce.getNonceKeyCount.call({ account: '0x...' }), - * Actions.nonce.getNonceKeyCount.call({ account: '0x...' }), - * ], - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { account } = args - return defineCall({ - address: Addresses.nonceManager, - abi: Abis.nonce, - args: [account], - functionName: 'getActiveNonceKeyCount', - }) - } -} - -/** - * Watches for nonce incremented events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), - * transport: http(), - * }) - * - * const unwatch = Actions.nonce.watchNonceIncremented(client, { - * onNonceIncremented: (args, log) => { - * console.log('Nonce incremented:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchNonceIncremented< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchNonceIncremented.Parameters, -) { - const { onNonceIncremented, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.nonceManager, - abi: Abis.nonce, - eventName: 'NonceIncremented', - onLogs: (logs) => { - for (const log of logs) onNonceIncremented(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchNonceIncremented { - export type Args = GetEventArgs< - typeof Abis.nonce, - 'NonceIncremented', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a nonce is incremented. */ - onNonceIncremented: (args: Args, log: Log) => void - } -} - -/** - * Watches for active key count changed events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), - * transport: http(), - * }) - * - * const unwatch = Actions.nonce.watchActiveKeyCountChanged(client, { - * onActiveKeyCountChanged: (args, log) => { - * console.log('Active key count changed:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchActiveKeyCountChanged< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchActiveKeyCountChanged.Parameters, -) { - const { onActiveKeyCountChanged, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.nonceManager, - abi: Abis.nonce, - eventName: 'ActiveKeyCountChanged', - onLogs: (logs) => { - for (const log of logs) onActiveKeyCountChanged(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchActiveKeyCountChanged { - export type Args = GetEventArgs< - typeof Abis.nonce, - 'ActiveKeyCountChanged', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters< - typeof Abis.nonce, - 'ActiveKeyCountChanged', - true - >, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when the active key count changes. */ - onActiveKeyCountChanged: (args: Args, log: Log) => void - } -} diff --git a/src/viem/Actions/policy.test.ts b/src/viem/Actions/policy.test.ts deleted file mode 100644 index c020f7a2..00000000 --- a/src/viem/Actions/policy.test.ts +++ /dev/null @@ -1,534 +0,0 @@ -import { setTimeout } from 'node:timers/promises' -import { beforeAll, describe, expect, test } from 'vitest' -import { rpcUrl } from '../../../test/config.js' -import { accounts, clientWithAccount } from '../../../test/viem/config.js' -import * as actions from './index.js' - -const account = accounts[0] -const account2 = accounts[1] -const account3 = accounts[2] - -describe('create', () => { - test('default', async () => { - // create whitelist policy - const { receipt, ...result } = await actions.policy.createSync( - clientWithAccount, - { - type: 'whitelist', - }, - ) - expect(receipt).toBeDefined() - expect(result).toMatchInlineSnapshot(` - { - "policyId": 2n, - "policyType": 0, - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - const { policyId } = result - - // verify policy was created - const data = await actions.policy.getData(clientWithAccount, { - policyId, - }) - expect(data.admin).toBe(account.address) - expect(data.type).toBe('whitelist') - }) - - test('behavior: blacklist', async () => { - // create blacklist policy - const { receipt: blacklistReceipt, ...blacklistResult } = - await actions.policy.createSync(clientWithAccount, { - type: 'blacklist', - }) - expect(blacklistReceipt).toBeDefined() - expect(blacklistResult).toMatchInlineSnapshot(` - { - "policyId": 3n, - "policyType": 1, - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - const { policyId } = blacklistResult - - // verify policy was created - const data = await actions.policy.getData(clientWithAccount, { - policyId, - }) - expect(data.admin).toBe(account.address) - expect(data.type).toBe('blacklist') - }) - - test.skip('behavior: with initial addresses', async () => { - // create policy with initial addresses - const { policyId } = await actions.policy.createSync(clientWithAccount, { - type: 'whitelist', - addresses: [account2.address, account3.address], - }) - - // verify addresses are whitelisted - const isAuthorized2 = await actions.policy.isAuthorized(clientWithAccount, { - policyId, - user: account2.address, - }) - expect(isAuthorized2).toBe(true) - - const isAuthorized3 = await actions.policy.isAuthorized(clientWithAccount, { - policyId, - user: account3.address, - }) - expect(isAuthorized3).toBe(true) - - // verify other address is not whitelisted - const isAuthorized = await actions.policy.isAuthorized(clientWithAccount, { - policyId, - user: account.address, - }) - expect(isAuthorized).toBe(false) - }) -}) - -describe('setAdmin', () => { - test('default', async () => { - // create policy - const { policyId } = await actions.policy.createSync(clientWithAccount, { - type: 'whitelist', - }) - - // set new admin - const { receipt: setAdminReceipt, ...setAdminResult } = - await actions.policy.setAdminSync(clientWithAccount, { - policyId, - admin: account2.address, - }) - expect(setAdminReceipt).toBeDefined() - expect(setAdminResult).toMatchInlineSnapshot(` - { - "admin": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - "policyId": 4n, - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - { - // verify new admin - const data = await actions.policy.getData(clientWithAccount, { - policyId, - }) - expect(data.admin).toBe(account2.address) - } - }) -}) - -describe('modifyWhitelist', () => { - test('default', async () => { - // create whitelist policy - const { policyId } = await actions.policy.createSync(clientWithAccount, { - type: 'whitelist', - }) - - { - // verify account2 is not authorized - const isAuthorized = await actions.policy.isAuthorized( - clientWithAccount, - { - policyId, - user: account2.address, - }, - ) - expect(isAuthorized).toBe(false) - } - - // add account2 to whitelist - const { receipt: addReceipt, ...addResult } = - await actions.policy.modifyWhitelistSync(clientWithAccount, { - policyId, - address: account2.address, - allowed: true, - }) - expect(addReceipt).toBeDefined() - expect(addResult).toMatchInlineSnapshot(` - { - "account": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - "allowed": true, - "policyId": 5n, - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - { - // verify account2 is authorized - const isAuthorized = await actions.policy.isAuthorized( - clientWithAccount, - { - policyId, - user: account2.address, - }, - ) - expect(isAuthorized).toBe(true) - } - - // remove account2 from whitelist - const { receipt: removeReceipt, ...removeResult } = - await actions.policy.modifyWhitelistSync(clientWithAccount, { - policyId, - address: account2.address, - allowed: false, - }) - expect(removeReceipt).toBeDefined() - expect(removeResult).toMatchInlineSnapshot(` - { - "account": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - "allowed": false, - "policyId": 5n, - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - { - // verify account2 is no longer authorized - const isAuthorized = await actions.policy.isAuthorized( - clientWithAccount, - { - policyId, - user: account2.address, - }, - ) - expect(isAuthorized).toBe(false) - } - }) -}) - -describe('modifyBlacklist', () => { - test('default', async () => { - // create blacklist policy - const { policyId } = await actions.policy.createSync(clientWithAccount, { - type: 'blacklist', - }) - - { - // verify account2 is authorized (not blacklisted) - const isAuthorized = await actions.policy.isAuthorized( - clientWithAccount, - { - policyId, - user: account2.address, - }, - ) - expect(isAuthorized).toBe(true) - } - - // add account2 to blacklist - const { receipt: addBlacklistReceipt, ...addBlacklistResult } = - await actions.policy.modifyBlacklistSync(clientWithAccount, { - policyId, - address: account2.address, - restricted: true, - }) - expect(addBlacklistReceipt).toBeDefined() - expect(addBlacklistResult).toMatchInlineSnapshot(` - { - "account": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - "policyId": 6n, - "restricted": true, - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - { - // verify account2 is not authorized (blacklisted) - const isAuthorized = await actions.policy.isAuthorized( - clientWithAccount, - { - policyId, - user: account2.address, - }, - ) - expect(isAuthorized).toBe(false) - } - - // remove account2 from blacklist - const { receipt: removeBlacklistReceipt, ...removeBlacklistResult } = - await actions.policy.modifyBlacklistSync(clientWithAccount, { - policyId, - address: account2.address, - restricted: false, - }) - expect(removeBlacklistReceipt).toBeDefined() - expect(removeBlacklistResult).toMatchInlineSnapshot(` - { - "account": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - "policyId": 6n, - "restricted": false, - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - { - // verify account2 is authorized again - const isAuthorized = await actions.policy.isAuthorized( - clientWithAccount, - { - policyId, - user: account2.address, - }, - ) - expect(isAuthorized).toBe(true) - } - }) -}) - -describe('getData', () => { - test('default', async () => { - // create policy - const { policyId } = await actions.policy.createSync(clientWithAccount, { - type: 'whitelist', - }) - - { - // get policy data - const data = await actions.policy.getData(clientWithAccount, { - policyId, - }) - expect(data.admin).toBe(account.address) - expect(data.type).toBe('whitelist') - } - }) - - test('behavior: blacklist', async () => { - // create blacklist policy - const { policyId } = await actions.policy.createSync(clientWithAccount, { - type: 'blacklist', - }) - - { - // get policy data - const data = await actions.policy.getData(clientWithAccount, { - policyId, - }) - expect(data.admin).toBe(account.address) - expect(data.type).toBe('blacklist') - } - }) -}) - -describe('isAuthorized', () => { - test('special policy: always-reject (policyId 0)', async () => { - const isAuthorized = await actions.policy.isAuthorized(clientWithAccount, { - policyId: 0n, - user: account.address, - }) - expect(isAuthorized).toBe(false) - }) - - test('special policy: always-allow (policyId 1)', async () => { - const isAuthorized = await actions.policy.isAuthorized(clientWithAccount, { - policyId: 1n, - user: account.address, - }) - expect(isAuthorized).toBe(true) - }) - - test.skip('whitelist policy', async () => { - // create whitelist policy - const { policyId } = await actions.policy.createSync(clientWithAccount, { - type: 'whitelist', - addresses: [account2.address], - }) - - { - // verify whitelisted address is authorized - const isAuthorized = await actions.policy.isAuthorized( - clientWithAccount, - { - policyId, - user: account2.address, - }, - ) - expect(isAuthorized).toBe(true) - } - - { - // verify non-whitelisted address is not authorized - const isAuthorized = await actions.policy.isAuthorized( - clientWithAccount, - { - policyId, - user: account.address, - }, - ) - expect(isAuthorized).toBe(false) - } - }) - - test.skip('blacklist policy', async () => { - // create blacklist policy - const { policyId } = await actions.policy.createSync(clientWithAccount, { - type: 'blacklist', - addresses: [account2.address], - }) - - { - // verify blacklisted address is not authorized - const isAuthorized = await actions.policy.isAuthorized( - clientWithAccount, - { - policyId, - user: account2.address, - }, - ) - expect(isAuthorized).toBe(false) - } - - { - // verify non-blacklisted address is authorized - const isAuthorized = await actions.policy.isAuthorized( - clientWithAccount, - { - policyId, - user: account.address, - }, - ) - expect(isAuthorized).toBe(true) - } - }) -}) - -describe('watchCreate', () => { - test('default', async () => { - const logs: any[] = [] - const unwatch = actions.policy.watchCreate(clientWithAccount, { - onPolicyCreated: (args, log) => { - logs.push({ args, log }) - }, - }) - - // create policy - await actions.policy.createSync(clientWithAccount, { - type: 'whitelist', - }) - - await setTimeout(500) - unwatch() - - expect(logs.length).toBe(1) - expect(logs[0].args.policyId).toBeDefined() - expect(logs[0].args.updater).toBe(account.address) - expect(logs[0].args.type).toBe('whitelist') - }) -}) - -describe('watchAdminUpdated', () => { - beforeAll(async () => { - await fetch(`${rpcUrl}/restart`) - }) - - test('default', async () => { - // create policy - const { policyId } = await actions.policy.createSync(clientWithAccount, { - type: 'whitelist', - }) - - const logs: any[] = [] - const unwatch = actions.policy.watchAdminUpdated(clientWithAccount, { - onAdminUpdated: (args, log) => { - logs.push({ args, log }) - }, - }) - - // set new admin - await actions.policy.setAdminSync(clientWithAccount, { - policyId, - admin: account2.address, - }) - - await setTimeout(500) - unwatch() - - expect(logs[0].args.policyId).toBeDefined() - expect(logs[0].args.updater).toBe(account.address) - expect(logs[0].args.admin).toBe(account2.address) - }) -}) - -describe('watchWhitelistUpdated', () => { - test('default', async () => { - // create whitelist policy - const { policyId } = await actions.policy.createSync(clientWithAccount, { - type: 'whitelist', - }) - - const logs: any[] = [] - const unwatch = actions.policy.watchWhitelistUpdated(clientWithAccount, { - onWhitelistUpdated: (args, log) => { - logs.push({ args, log }) - }, - }) - - // add address to whitelist - await actions.policy.modifyWhitelistSync(clientWithAccount, { - policyId, - address: account2.address, - allowed: true, - }) - - // remove address from whitelist - await actions.policy.modifyWhitelistSync(clientWithAccount, { - policyId, - address: account2.address, - allowed: false, - }) - - await setTimeout(500) - unwatch() - - expect(logs.length).toBe(2) - expect(logs[0].args.policyId).toBeDefined() - expect(logs[0].args.updater).toBe(account.address) - expect(logs[0].args.account).toBe(account2.address) - expect(logs[0].args.allowed).toBe(true) - expect(logs[1].args.allowed).toBe(false) - }) -}) - -describe('watchBlacklistUpdated', () => { - test('default', async () => { - // create blacklist policy - const { policyId } = await actions.policy.createSync(clientWithAccount, { - type: 'blacklist', - }) - - const logs: any[] = [] - const unwatch = actions.policy.watchBlacklistUpdated(clientWithAccount, { - onBlacklistUpdated: (args, log) => { - logs.push({ args, log }) - }, - }) - - // add address to blacklist - await actions.policy.modifyBlacklistSync(clientWithAccount, { - policyId, - address: account2.address, - restricted: true, - }) - - // remove address from blacklist - await actions.policy.modifyBlacklistSync(clientWithAccount, { - policyId, - address: account2.address, - restricted: false, - }) - - await setTimeout(500) - unwatch() - - expect(logs.length).toBe(2) - expect(logs[0].args.policyId).toBeDefined() - expect(logs[0].args.updater).toBe(account.address) - expect(logs[0].args.account).toBe(account2.address) - expect(logs[0].args.restricted).toBe(true) - expect(logs[1].args.restricted).toBe(false) - }) -}) diff --git a/src/viem/Actions/policy.ts b/src/viem/Actions/policy.ts deleted file mode 100644 index 166de667..00000000 --- a/src/viem/Actions/policy.ts +++ /dev/null @@ -1,1335 +0,0 @@ -import { - type Account, - type Address, - type BaseErrorType, - type Chain, - type Client, - type ExtractAbiItem, - type GetEventArgs, - type Log, - parseEventLogs, - type ReadContractReturnType, - type TransactionReceipt, - type Transport, - type Log as viem_Log, - type WatchContractEventParameters, - type WriteContractReturnType, -} from 'viem' -import { parseAccount } from 'viem/accounts' -import { - readContract, - watchContractEvent, - writeContract, - writeContractSync, -} from 'viem/actions' -import type { Compute, UnionOmit } from '../../internal/types.js' -import * as Abis from '../Abis.js' -import * as Addresses from '../Addresses.js' -import type { ReadParameters, WriteParameters } from '../internal/types.js' -import { defineCall } from '../internal/utils.js' - -export type PolicyType = 'whitelist' | 'blacklist' - -const policyTypeMap = { - whitelist: 0, - blacklist: 1, -} as const - -/** - * Creates a new policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const { hash, policyId } = await Actions.policy.create(client, { - * admin: '0x...', - * type: 'whitelist', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash and policy ID. - */ -export async function create< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: create.Parameters, -): Promise { - return create.inner(writeContract, client, parameters) -} - -export namespace create { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & - Omit & { - /** Address of the policy admin. */ - admin?: Address | undefined - } - - export type Args = { - /** Optional array of accounts to initialize the policy with. */ - addresses?: readonly Address[] | undefined - /** Address of the policy admin. */ - admin: Address - /** Type of policy to create. */ - type: PolicyType - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: Parameters, - ): Promise> { - const { - account = client.account, - addresses, - chain = client.chain, - type, - ...rest - } = parameters - - if (!account) throw new Error('`account` is required') - - const admin = parseAccount(account).address! - - const call = create.call({ admin, type, addresses }) - return action(client, { - ...rest, - account, - chain, - ...call, - } as never) as never - } - - /** - * Defines a call to the `createPolicy` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.policy.create.call({ - * admin: '0xfeed...fede', - * type: 'whitelist', - * }), - * actions.policy.create.call({ - * admin: '0xfeed...fede', - * type: 'blacklist', - * addresses: ['0x20c0...beef', '0x20c0...babe'], - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { admin, type, addresses } = args - const config = (() => { - if (addresses) - return { - functionName: 'createPolicyWithAccounts', - args: [admin, policyTypeMap[type], addresses], - } as const - return { - functionName: 'createPolicy', - args: [admin, policyTypeMap[type]], - } as const - })() - return defineCall({ - address: Addresses.tip403Registry, - abi: Abis.tip403Registry, - ...config, - }) - } - - /** - * Extracts the `PolicyCreated` event from logs. - * - * @param logs - The logs. - * @returns The `PolicyCreated` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip403Registry, - logs, - eventName: 'PolicyCreated', - strict: true, - }) - if (!log) throw new Error('`PolicyCreated` event not found.') - return log - } -} - -/** - * Creates a new policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.policy.createSync(client, { - * admin: '0x...', - * type: 'whitelist', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function createSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: createSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await create.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = create.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace createSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = create.Parameters - - export type Args = create.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip403Registry, - 'PolicyCreated', - { IndexedOnly: false; Required: true } - > & { - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Sets the admin for a policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.policy.setAdmin(client, { - * policyId: 2n, - * admin: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function setAdmin< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: setAdmin.Parameters, -): Promise { - return setAdmin.inner(writeContract, client, parameters) -} - -export namespace setAdmin { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** New admin address. */ - admin: Address - /** Policy ID. */ - policyId: bigint - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: setAdmin.Parameters, - ): Promise> { - const { policyId, admin, ...rest } = parameters - const call = setAdmin.call({ policyId, admin }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `setPolicyAdmin` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.policy.setAdmin.call({ - * policyId: 2n, - * admin: '0xfeed...fede', - * }), - * actions.policy.setAdmin.call({ - * policyId: 3n, - * admin: '0xfeed...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { policyId, admin } = args - return defineCall({ - address: Addresses.tip403Registry, - abi: Abis.tip403Registry, - functionName: 'setPolicyAdmin', - args: [policyId, admin], - }) - } - - /** - * Extracts the `PolicyAdminUpdated` event from logs. - * - * @param logs - The logs. - * @returns The `PolicyAdminUpdated` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip403Registry, - logs, - eventName: 'PolicyAdminUpdated', - strict: true, - }) - if (!log) throw new Error('`PolicyAdminUpdated` event not found.') - return log - } -} - -/** - * Sets the admin for a policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.policy.setAdminSync(client, { - * policyId: 2n, - * admin: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function setAdminSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: setAdminSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await setAdmin.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = setAdmin.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace setAdminSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = setAdmin.Parameters - - export type Args = setAdmin.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip403Registry, - 'PolicyAdminUpdated', - { IndexedOnly: false; Required: true } - > & { - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Modifies a policy whitelist. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.policy.modifyWhitelist(client, { - * policyId: 2n, - * account: '0x...', - * allowed: true, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function modifyWhitelist< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: modifyWhitelist.Parameters, -): Promise { - return modifyWhitelist.inner(writeContract, client, parameters) -} - -export namespace modifyWhitelist { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Target account address. */ - address: Address - /** Whether the account is allowed. */ - allowed: boolean - /** Policy ID. */ - policyId: bigint - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: modifyWhitelist.Parameters, - ): Promise> { - const { address: targetAccount, allowed, policyId, ...rest } = parameters - const call = modifyWhitelist.call({ - address: targetAccount, - allowed, - policyId, - }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `modifyPolicyWhitelist` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.policy.modifyWhitelist.call({ - * policyId: 2n, - * address: '0x20c0...beef', - * allowed: true, - * }), - * actions.policy.modifyWhitelist.call({ - * policyId: 2n, - * address: '0x20c0...babe', - * allowed: false, - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { policyId, address, allowed } = args - return defineCall({ - address: Addresses.tip403Registry, - abi: Abis.tip403Registry, - functionName: 'modifyPolicyWhitelist', - args: [policyId, address, allowed], - }) - } - - /** - * Extracts the `WhitelistUpdated` event from logs. - * - * @param logs - The logs. - * @returns The `WhitelistUpdated` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip403Registry, - logs, - eventName: 'WhitelistUpdated', - strict: true, - }) - if (!log) throw new Error('`WhitelistUpdated` event not found.') - return log - } -} - -/** - * Modifies a policy whitelist. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.policy.modifyWhitelistSync(client, { - * policyId: 2n, - * account: '0x...', - * allowed: true, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function modifyWhitelistSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: modifyWhitelistSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await modifyWhitelist.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = modifyWhitelist.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace modifyWhitelistSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = modifyWhitelist.Parameters - - export type Args = modifyWhitelist.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip403Registry, - 'WhitelistUpdated', - { IndexedOnly: false; Required: true } - > & { - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Modifies a policy blacklist. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.policy.modifyBlacklist(client, { - * policyId: 2n, - * account: '0x...', - * restricted: true, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function modifyBlacklist< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: modifyBlacklist.Parameters, -): Promise { - return modifyBlacklist.inner(writeContract, client, parameters) -} - -export namespace modifyBlacklist { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Target account address. */ - address: Address - /** Policy ID. */ - policyId: bigint - /** Whether the account is restricted. */ - restricted: boolean - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: modifyBlacklist.Parameters, - ): Promise> { - const { address: targetAccount, policyId, restricted, ...rest } = parameters - const call = modifyBlacklist.call({ - address: targetAccount, - policyId, - restricted, - }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `modifyPolicyBlacklist` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.policy.modifyBlacklist.call({ - * policyId: 2n, - * address: '0x20c0...beef', - * restricted: true, - * }), - * actions.policy.modifyBlacklist.call({ - * policyId: 2n, - * address: '0x20c0...babe', - * restricted: false, - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { policyId, address, restricted } = args - return defineCall({ - address: Addresses.tip403Registry, - abi: Abis.tip403Registry, - functionName: 'modifyPolicyBlacklist', - args: [policyId, address, restricted], - }) - } - - /** - * Extracts the `BlacklistUpdated` event from logs. - * - * @param logs - The logs. - * @returns The `BlacklistUpdated` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip403Registry, - logs, - eventName: 'BlacklistUpdated', - strict: true, - }) - if (!log) throw new Error('`BlacklistUpdated` event not found.') - return log - } -} - -/** - * Modifies a policy blacklist. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.policy.modifyBlacklistSync(client, { - * policyId: 2n, - * account: '0x...', - * restricted: true, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function modifyBlacklistSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: modifyBlacklistSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await modifyBlacklist.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = modifyBlacklist.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace modifyBlacklistSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = modifyBlacklist.Parameters - - export type Args = modifyBlacklist.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip403Registry, - 'BlacklistUpdated', - { IndexedOnly: false; Required: true } - > & { - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Gets policy data. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const data = await Actions.policy.getData(client, { - * policyId: 2n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The policy data. - */ -export async function getData( - client: Client, - parameters: getData.Parameters, -): Promise { - const { policyId, ...rest } = parameters - const result = await readContract(client, { - ...rest, - ...getData.call({ policyId }), - }) - return { - admin: result[1], - type: result[0] === 0 ? 'whitelist' : 'blacklist', - } -} - -export namespace getData { - export type Parameters = ReadParameters & Args - - export type Args = { - /** Policy ID. */ - policyId: bigint - } - - export type ReturnValue = Compute<{ - /** Admin address. */ - admin: Address - /** Policy type. */ - type: PolicyType - }> - - /** - * Defines a call to the `policyData` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { policyId } = args - return defineCall({ - address: Addresses.tip403Registry, - abi: Abis.tip403Registry, - args: [policyId], - functionName: 'policyData', - }) - } -} - -/** - * Checks if a user is authorized by a policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const authorized = await Actions.policy.isAuthorized(client, { - * policyId: 2n, - * user: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns Whether the user is authorized. - */ -export async function isAuthorized( - client: Client, - parameters: isAuthorized.Parameters, -): Promise { - const { policyId, user, ...rest } = parameters - return readContract(client, { - ...rest, - ...isAuthorized.call({ policyId, user }), - }) -} - -export namespace isAuthorized { - export type Parameters = ReadParameters & Args - - export type Args = { - /** Policy ID. */ - policyId: bigint - /** User address to check. */ - user: Address - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.tip403Registry, - 'isAuthorized', - never - > - - /** - * Defines a call to the `isAuthorized` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { policyId, user } = args - return defineCall({ - address: Addresses.tip403Registry, - abi: Abis.tip403Registry, - args: [policyId, user], - functionName: 'isAuthorized', - }) - } -} - -/** - * Watches for policy creation events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.policy.watchCreate(client, { - * onPolicyCreated: (args, log) => { - * console.log('Policy created:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchCreate< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchCreate.Parameters, -) { - const { onPolicyCreated, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.tip403Registry, - abi: Abis.tip403Registry, - eventName: 'PolicyCreated', - onLogs: (logs) => { - for (const log of logs) - onPolicyCreated( - { - ...log.args, - type: log.args.policyType === 0 ? 'whitelist' : 'blacklist', - }, - log, - ) - }, - strict: true, - }) -} - -export declare namespace watchCreate { - export type Args = Compute<{ - policyId: bigint - updater: Address - type: PolicyType - }> - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters< - typeof Abis.tip403Registry, - 'PolicyCreated', - true - >, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a policy is created. */ - onPolicyCreated: (args: Args, log: Log) => void - } -} - -/** - * Watches for policy admin update events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.policy.watchAdminUpdated(client, { - * onAdminUpdated: (args, log) => { - * console.log('Policy admin updated:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchAdminUpdated< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchAdminUpdated.Parameters, -) { - const { onAdminUpdated, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.tip403Registry, - abi: Abis.tip403Registry, - eventName: 'PolicyAdminUpdated', - onLogs: (logs) => { - for (const log of logs) onAdminUpdated(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchAdminUpdated { - export type Args = GetEventArgs< - typeof Abis.tip403Registry, - 'PolicyAdminUpdated', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters< - typeof Abis.tip403Registry, - 'PolicyAdminUpdated', - true - >, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a policy admin is updated. */ - onAdminUpdated: (args: Args, log: Log) => void - } -} - -/** - * Watches for whitelist update events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.policy.watchWhitelistUpdated(client, { - * onWhitelistUpdated: (args, log) => { - * console.log('Whitelist updated:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchWhitelistUpdated< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchWhitelistUpdated.Parameters, -) { - const { onWhitelistUpdated, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.tip403Registry, - abi: Abis.tip403Registry, - eventName: 'WhitelistUpdated', - onLogs: (logs) => { - for (const log of logs) onWhitelistUpdated(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchWhitelistUpdated { - export type Args = GetEventArgs< - typeof Abis.tip403Registry, - 'WhitelistUpdated', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters< - typeof Abis.tip403Registry, - 'WhitelistUpdated', - true - >, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a whitelist is updated. */ - onWhitelistUpdated: (args: Args, log: Log) => void - } -} - -/** - * Watches for blacklist update events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.policy.watchBlacklistUpdated(client, { - * onBlacklistUpdated: (args, log) => { - * console.log('Blacklist updated:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchBlacklistUpdated< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchBlacklistUpdated.Parameters, -) { - const { onBlacklistUpdated, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.tip403Registry, - abi: Abis.tip403Registry, - eventName: 'BlacklistUpdated', - onLogs: (logs) => { - for (const log of logs) onBlacklistUpdated(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchBlacklistUpdated { - export type Args = GetEventArgs< - typeof Abis.tip403Registry, - 'BlacklistUpdated', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters< - typeof Abis.tip403Registry, - 'BlacklistUpdated', - true - >, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a blacklist is updated. */ - onBlacklistUpdated: (args: Args, log: Log) => void - } -} diff --git a/src/viem/Actions/reward.test.ts b/src/viem/Actions/reward.test.ts deleted file mode 100644 index 0d61b546..00000000 --- a/src/viem/Actions/reward.test.ts +++ /dev/null @@ -1,434 +0,0 @@ -import { parseUnits } from 'viem' -import { describe, expect, test } from 'vitest' -import { clientWithAccount, setupToken } from '../../../test/viem/config.js' -import * as actions from './index.js' - -const account = clientWithAccount.account - -describe('claimSync', () => { - test('default', async () => { - const { token } = await setupToken(clientWithAccount) - - const balanceBefore = await actions.token.getBalance(clientWithAccount, { - token, - }) - - // Opt in to rewards - await actions.reward.setRecipientSync(clientWithAccount, { - recipient: account.address, - token, - }) - - // Mint reward tokens - const rewardAmount = parseUnits('100', 6) - await actions.token.mintSync(clientWithAccount, { - amount: rewardAmount, - to: account.address, - token, - }) - - // Start immediate reward to distribute rewards - await actions.reward.startSync(clientWithAccount, { - amount: rewardAmount, - token, - }) - - // Trigger reward accrual by transferring - await actions.token.transferSync(clientWithAccount, { - amount: 1n, - to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', - token, - }) - - // Claim rewards - await actions.reward.claimSync(clientWithAccount, { - token, - }) - - const balanceAfter = await actions.token.getBalance(clientWithAccount, { - token, - }) - - expect(balanceAfter).toBeGreaterThan( - balanceBefore + rewardAmount - parseUnits('1', 6), - ) - }) - - test('behavior: claiming from streaming reward', async () => { - const { token } = await setupToken(clientWithAccount) - - const balanceBefore = await actions.token.getBalance(clientWithAccount, { - token, - }) - - // Mint tokens to have balance - const mintAmount = parseUnits('1000', 6) - await actions.token.mintSync(clientWithAccount, { - amount: mintAmount, - to: account.address, - token, - }) - - // Opt in to rewards - await actions.reward.setRecipientSync(clientWithAccount, { - recipient: account.address, - token, - }) - - // Mint reward tokens - const rewardAmount = parseUnits('100', 6) - await actions.token.mintSync(clientWithAccount, { - amount: rewardAmount, - to: account.address, - token, - }) - - // Start a streaming reward (not immediate) - await actions.reward.startSync(clientWithAccount, { - amount: rewardAmount, - token, - }) - - // Wait a bit and trigger accrual by transferring - await new Promise((resolve) => setTimeout(resolve, 2000)) - await actions.token.transferSync(clientWithAccount, { - amount: 1n, - to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', - token, - }) - - // Claim accumulated rewards from the stream - await actions.reward.claimSync(clientWithAccount, { - token, - }) - - const balanceAfter = await actions.token.getBalance(clientWithAccount, { - token, - }) - - // Should have accumulated some rewards (at least 10% of total after 2 seconds) - expect(balanceAfter).toBeGreaterThan(balanceBefore + rewardAmount / 10n) - }) -}) - -describe('getTotalPerSecond', () => { - test('default', async () => { - const { token } = await setupToken(clientWithAccount) - - const rate = await actions.reward.getTotalPerSecond(clientWithAccount, { - token, - }) - - expect(rate).toBe(0n) - }) -}) - -describe('getUserRewardInfo', () => { - test('default', async () => { - const { token } = await setupToken(clientWithAccount) - - const info = await actions.reward.getUserRewardInfo(clientWithAccount, { - token, - account: account.address, - }) - - expect(info.rewardRecipient).toBeDefined() - expect(info.rewardPerToken).toBeDefined() - expect(info.rewardBalance).toBeDefined() - expect(info.rewardRecipient).toBe( - '0x0000000000000000000000000000000000000000', - ) - expect(info.rewardPerToken).toBe(0n) - expect(info.rewardBalance).toBe(0n) - }) - - test('behavior: after opting in', async () => { - const { token } = await setupToken(clientWithAccount) - - // Opt in to rewards - await actions.reward.setRecipientSync(clientWithAccount, { - recipient: account.address, - token, - }) - - const info = await actions.reward.getUserRewardInfo(clientWithAccount, { - token, - account: account.address, - }) - - expect(info.rewardRecipient).toBe(account.address) - expect(info.rewardPerToken).toBe(0n) - expect(info.rewardBalance).toBe(0n) - }) - - test('behavior: with active rewards after distribution', async () => { - const { token } = await setupToken(clientWithAccount) - - // Opt in to rewards - await actions.reward.setRecipientSync(clientWithAccount, { - recipient: account.address, - token, - }) - - // Mint reward tokens - const rewardAmount = parseUnits('100', 6) - await actions.token.mintSync(clientWithAccount, { - amount: rewardAmount, - to: account.address, - token, - }) - - // Start immediate reward to distribute rewards - await actions.reward.startSync(clientWithAccount, { - amount: rewardAmount, - token, - }) - - // Trigger reward accrual by transferring - await actions.token.transferSync(clientWithAccount, { - amount: 1n, - to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', - token, - }) - - // Check reward info shows accumulated rewards - const info = await actions.reward.getUserRewardInfo(clientWithAccount, { - token, - account: account.address, - }) - - expect(info.rewardRecipient).toBe(account.address) - expect(info.rewardPerToken).toBeGreaterThan(0n) - expect(info.rewardBalance).toBeGreaterThan(0n) - // Should have approximately the full reward amount (minus the 1 token transferred) - expect(info.rewardBalance).toBeGreaterThanOrEqual( - rewardAmount - parseUnits('1', 6), - ) - }) -}) - -describe('setRecipientSync', () => { - test('default', async () => { - const { token } = await setupToken(clientWithAccount) - - // Set reward recipient to self - const { holder, receipt, recipient } = - await actions.reward.setRecipientSync(clientWithAccount, { - recipient: account.address, - token, - }) - - expect(receipt).toBeDefined() - expect(holder).toBe(account.address) - expect(recipient).toBe(account.address) - }) - - test('behavior: opt out with zero address', async () => { - const { token } = await setupToken(clientWithAccount) - - // First opt in - await actions.reward.setRecipientSync(clientWithAccount, { - recipient: account.address, - token, - }) - - // Then opt out - const { holder, recipient } = await actions.reward.setRecipientSync( - clientWithAccount, - { - recipient: '0x0000000000000000000000000000000000000000', - token, - }, - ) - - expect(holder).toBe(account.address) - expect(recipient).toBe('0x0000000000000000000000000000000000000000') - }) -}) - -describe('startSync', () => { - test('behavior: immediate distribution (seconds = 0)', async () => { - const { token } = await setupToken(clientWithAccount) - - // Opt in to rewards - await actions.reward.setRecipientSync(clientWithAccount, { - recipient: account.address, - token, - }) - - const balanceBeforeReward = await actions.token.getBalance( - clientWithAccount, - { - token, - }, - ) - - // Mint reward tokens - const rewardAmount = parseUnits('100', 6) - await actions.token.mintSync(clientWithAccount, { - amount: rewardAmount, - to: account.address, - token, - }) - - // Start immediate reward - const { id } = await actions.reward.startSync(clientWithAccount, { - amount: rewardAmount, - token, - }) - - expect(id).toBe(0n) // Immediate distributions return ID 0 - - // Trigger reward distribution by transferring - await actions.token.transferSync(clientWithAccount, { - amount: 1n, - to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', - token, - }) - - // Claim the accumulated rewards - await actions.reward.claimSync(clientWithAccount, { - token, - }) - - const balanceAfter = await actions.token.getBalance(clientWithAccount, { - token, - }) - - // Account should have received rewards - expect(balanceAfter).toBeGreaterThanOrEqual( - balanceBeforeReward + rewardAmount - 1n, - ) - - // Total reward per second should be zero for immediate distributions - const totalRate = await actions.reward.getTotalPerSecond( - clientWithAccount, - { - token, - }, - ) - expect(totalRate).toBe(0n) - }) - - test('behavior: immediate distribution with opted-in holders', async () => { - const { token } = await setupToken(clientWithAccount) - - // Opt in to rewards - await actions.reward.setRecipientSync(clientWithAccount, { - recipient: account.address, - token, - }) - - // Mint reward tokens - const rewardAmount = parseUnits('100', 6) - await actions.token.mintSync(clientWithAccount, { - amount: rewardAmount, - to: account.address, - token, - }) - - // Start immediate reward - const { amount, durationSeconds, funder, id } = - await actions.reward.startSync(clientWithAccount, { - amount: rewardAmount, - token, - }) - - expect(id).toBe(0n) // Immediate distributions return ID 0 - expect(funder).toBe(account.address) - expect(amount).toBe(rewardAmount) - expect(durationSeconds).toBe(0) - - // Total reward per second should be zero for immediate distributions - const totalRate = await actions.reward.getTotalPerSecond( - clientWithAccount, - { - token, - }, - ) - expect(totalRate).toBe(0n) - }) -}) - -describe('watchRewardScheduled', () => { - test('default', async () => { - const { token } = await setupToken(clientWithAccount) - - // Opt in to rewards - await actions.reward.setRecipientSync(clientWithAccount, { - recipient: account.address, - token, - }) - - // Mint reward tokens - const rewardAmount = parseUnits('100', 6) - await actions.token.mintSync(clientWithAccount, { - amount: rewardAmount, - to: account.address, - token, - }) - - const events: Array<{ - args: actions.reward.watchRewardScheduled.Args - log: actions.reward.watchRewardScheduled.Log - }> = [] - - const unwatch = actions.reward.watchRewardScheduled(clientWithAccount, { - token, - onRewardScheduled: (args, log) => { - events.push({ args, log }) - }, - }) - - try { - await actions.reward.startSync(clientWithAccount, { - amount: rewardAmount, - token, - }) - - await new Promise((resolve) => setTimeout(resolve, 500)) - - expect(events.length).toBeGreaterThan(0) - expect(events[0]?.args.amount).toBe(rewardAmount) - expect(events[0]?.args.funder).toBe(account.address) - expect(events[0]?.args.durationSeconds).toBe(0) - expect(events[0]?.log).toBeDefined() - } finally { - if (unwatch) unwatch() - } - }) -}) - -describe('watchRewardRecipientSet', () => { - test('default', async () => { - const { token } = await setupToken(clientWithAccount) - - const events: Array<{ - args: actions.reward.watchRewardRecipientSet.Args - log: actions.reward.watchRewardRecipientSet.Log - }> = [] - - const unwatch = actions.reward.watchRewardRecipientSet(clientWithAccount, { - token, - onRewardRecipientSet: (args, log) => { - events.push({ args, log }) - }, - }) - - try { - await actions.reward.setRecipientSync(clientWithAccount, { - recipient: account.address, - token, - }) - - await new Promise((resolve) => setTimeout(resolve, 500)) - - expect(events.length).toBeGreaterThan(0) - expect(events[0]?.args.holder).toBe(account.address) - expect(events[0]?.args.recipient).toBe(account.address) - expect(events[0]?.log).toBeDefined() - } finally { - if (unwatch) unwatch() - } - }) -}) diff --git a/src/viem/Actions/reward.ts b/src/viem/Actions/reward.ts deleted file mode 100644 index d6874a5c..00000000 --- a/src/viem/Actions/reward.ts +++ /dev/null @@ -1,944 +0,0 @@ -import { - type Account, - type Address, - type BaseErrorType, - type Chain, - type Client, - type ExtractAbiItem, - type GetEventArgs, - type Log, - parseEventLogs, - type ReadContractReturnType, - type Transport, - type Log as viem_Log, - type WatchContractEventParameters, - type WatchContractEventReturnType, - type WriteContractReturnType, -} from 'viem' -import { - readContract, - watchContractEvent, - writeContract, - writeContractSync, -} from 'viem/actions' -import type { UnionOmit } from '../../internal/types.js' -import * as Abis from '../Abis.js' -import type { ReadParameters, WriteParameters } from '../internal/types.js' -import { defineCall } from '../internal/utils.js' - -/** - * Claims accumulated rewards for a recipient. - * - * This function allows a reward recipient to claim their accumulated rewards - * and receive them as token transfers to their own balance. - * - * - Accrues all pending rewards up to the current block timestamp. - * - Updates the caller's reward accounting. - * - Transfers the caller's accumulated `rewardBalance` from the token contract to the caller. - * - If the contract's balance is insufficient, claims up to the available amount. - * - Returns the actual amount claimed. - * - * Notes: - * - Reverts with `Paused` if the token is paused. - * - Reverts with `PolicyForbids` if the caller is not authorized to receive tokens under TIP-403. - * - If opted in, the claimed amount is added back to `optedInSupply` since it goes to the recipient's balance. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.reward.claim(client, { - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function claim< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: claim.Parameters, -): Promise { - return claim.inner(writeContract, client, parameters) -} - -export namespace claim { - export type Args = { - /** The TIP20 token address */ - token: Address - } - - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: Parameters, - ): Promise> { - const { token, ...rest } = parameters - const call = claim.call({ token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `claimRewards` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const hash = await client.sendTransaction({ - * calls: [actions.reward.claim.call({ - * token: '0x20c0000000000000000000000000000000000001', - * })], - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token } = args - return defineCall({ - address: token, - abi: Abis.tip20, - args: [], - functionName: 'claimRewards', - }) - } -} - -/** - * Claims accumulated rewards for a recipient and waits for confirmation. - * - * This function allows a reward recipient to claim their accumulated rewards - * and receive them as token transfers to their own balance. - * - * Behavior: - * - Accrues all pending rewards up to the current block timestamp. - * - Updates the caller's reward accounting. - * - Transfers the caller's accumulated `rewardBalance` from the token contract to the caller. - * - If the contract's balance is insufficient, claims up to the available amount. - * - * Notes: - * - Reverts with `Paused` if the token is paused. - * - Reverts with `PolicyForbids` if the caller is not authorized to receive tokens under TIP-403. - * - If opted in, the claimed amount is added back to `optedInSupply` since it goes to the recipient's balance. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const { receipt } = await Actions.reward.claimSync(client, { - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The amount claimed and transaction receipt. - */ -export async function claimSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: claimSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await claim.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - return { - receipt, - } as never -} - -export namespace claimSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & claim.Args - - export type ReturnValue = { - /** The transaction receipt */ - receipt: Awaited> - } - - export type ErrorType = claim.ErrorType -} - -/** - * Gets the total reward per second rate for all active streams. - * - * Returns the current aggregate per-second emission rate scaled by `ACC_PRECISION` (1e18). - * This value represents the sum of all active reward streams' emission rates. - * The rate decreases when streams end (via `finalizeStreams`) or are canceled. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const rate = await Actions.rewards.getTotalPerSecond(client, { - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The total reward per second (scaled by 1e18). - */ -export async function getTotalPerSecond( - client: Client, - parameters: getTotalPerSecond.Parameters, -): Promise { - return readContract(client, { - ...parameters, - ...getTotalPerSecond.call(parameters), - }) -} - -export namespace getTotalPerSecond { - export type Parameters = ReadParameters & Args - - export type Args = { - /** The TIP20 token address */ - token: Address - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.tip20, - 'totalRewardPerSecond', - never - > - - /** - * Defines a call to the `totalRewardPerSecond` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token } = args - return defineCall({ - address: token, - abi: Abis.tip20, - args: [], - functionName: 'totalRewardPerSecond', - }) - } -} - -/** - * Gets the reward information for a specific account. - * - * Returns the reward recipient address, reward per token value, and accumulated reward balance for the specified account. - * This information includes: - * - `rewardRecipient`: The address designated to receive rewards (zero address if opted out) - * - `rewardPerToken`: The reward per token value for this account - * - `rewardBalance`: The accumulated reward balance waiting to be claimed - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const info = await Actions.reward.getUserRewardInfo(client, { - * token: '0x20c0000000000000000000000000000000000001', - * account: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The user's reward information (recipient, rewardPerToken, rewardBalance). - */ -export async function getUserRewardInfo( - client: Client, - parameters: getUserRewardInfo.Parameters, -): Promise { - return readContract(client, { - ...parameters, - ...getUserRewardInfo.call(parameters), - }) -} - -export namespace getUserRewardInfo { - export type Parameters = ReadParameters & Args - - export type Args = { - /** The account address to query reward info for */ - account: Address - /** The TIP20 token address */ - token: Address - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.tip20, - 'userRewardInfo', - never - > - - /** - * Defines a call to the `userRewardInfo` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { account, token } = args - return defineCall({ - address: token, - abi: Abis.tip20, - args: [account], - functionName: 'userRewardInfo', - }) - } -} - -/** - * Sets or changes the reward recipient for a token holder. - * - * This function allows a token holder to designate who should receive their share of rewards: - * - If `recipient` is the zero address, opts out from rewards distribution. - * - Otherwise, opts in and sets `recipient` as the address that will receive accrued rewards. - * - Can be called with `recipient == msg.sender` to receive rewards directly. - * - Automatically distributes any accrued rewards to the current recipient before changing. - * - * TIP-403 Policy: - * - Reverts with `PolicyForbids` if `recipient` is not the zero address and either the holder or recipient is not authorized to receive tokens under the token's transfer policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.rewards.setRecipient(client, { - * recipient: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function setRecipient< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: setRecipient.Parameters, -): Promise { - return setRecipient.inner(writeContract, client, parameters) -} - -/** - * Sets or changes the reward recipient for a token holder and waits for confirmation. - * - * This function allows a token holder to designate who should receive their share of rewards: - * - If `recipient` is the zero address, opts out from rewards distribution. - * - Otherwise, opts in and sets `recipient` as the address that will receive accrued rewards. - * - Can be called with `recipient == msg.sender` to receive rewards directly. - * - Automatically distributes any accrued rewards to the current recipient before changing. - * - * TIP-403 Policy: - * - Reverts with `PolicyForbids` if `recipient` is not the zero address and either the holder or recipient is not authorized to receive tokens under the token's transfer policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const { holder, recipient, receipt } = await Actions.rewards.setRecipientSync(client, { - * recipient: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The holder, recipient, and transaction receipt. - */ -export async function setRecipientSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: setRecipientSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await setRecipient.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = setRecipient.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace setRecipient { - export type Args = { - /** The reward recipient address (use zero address to opt out of rewards) */ - recipient: Address - /** The TIP20 token address */ - token: Address - } - - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: Parameters, - ): Promise> { - const { recipient, token, ...rest } = parameters - const call = setRecipient.call({ recipient, token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `setRecipient` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const hash = await client.sendTransaction({ - * calls: [actions.rewards.setRecipient.call({ - * recipient: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', - * token: '0x20c0000000000000000000000000000000000001', - * })], - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { recipient, token } = args - return defineCall({ - address: token, - abi: Abis.tip20, - args: [recipient], - functionName: 'setRewardRecipient', - }) - } - - /** - * Extracts the `RewardRecipientSet` event from logs. - * - * @param logs - The logs. - * @returns The `RewardRecipientSet` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'RewardRecipientSet', - strict: true, - }) - if (!log) throw new Error('`RewardRecipientSet` event not found.') - return log - } -} - -export declare namespace setRecipientSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & setRecipient.Args - - export type ReturnValue = { - /** The token holder address who set their reward recipient */ - holder: Address - /** The transaction receipt */ - receipt: Awaited> - /** The reward recipient address (zero address indicates opt-out) */ - recipient: Address - } - - export type ErrorType = setRecipient.ErrorType -} - -/** - * Starts a new reward stream that distributes tokens to opted-in holders. - * - * Behavior: - * - Transfers `amount` of tokens from the caller into the token contract's reward pool. - * - If `seconds == 0`: Immediately distributes `amount` to current opted-in holders by increasing `rewardPerTokenStored`. - * Returns stream ID `0`. Distribution occurs when holders interact with the token (transfers, etc.). - * - If `seconds > 0`: Starts a linear stream that emits evenly from `block.timestamp` to `block.timestamp + seconds`. - * Returns a unique stream ID for later cancellation. - * - * Notes: - * - Reverts with `InvalidAmount` if `amount == 0`. - * - Allowed even when `optedInSupply == 0` (tokens distributed while no one is opted in are locked permanently). - * - The transfer from caller to pool is subject to TIP-403 policy checks. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hash = await Actions.rewards.start(client, { - * amount: 100000000000000000000n, - * seconds: 86400, - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function start< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: start.Parameters, -): Promise { - return start.inner(writeContract, client, parameters) -} - -/** - * Starts a new reward stream that distributes tokens to opted-in holders and waits for confirmation. - * - * Behavior: - * - Transfers `amount` of tokens from the caller into the token contract's reward pool. - * - If `seconds == 0`: Immediately distributes `amount` to current opted-in holders by increasing `rewardPerTokenStored`. - * Returns stream ID `0`. Distribution occurs when holders interact with the token (transfers, etc.). - * - If `seconds > 0`: Starts a linear stream that emits evenly from `block.timestamp` to `block.timestamp + seconds`. - * Returns a unique stream ID for later cancellation. - * - * Notes: - * - Reverts with `InvalidAmount` if `amount == 0`. - * - Allowed even when `optedInSupply == 0` (tokens distributed while no one is opted in are locked permanently). - * - The transfer from caller to pool is subject to TIP-403 policy checks. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const { id, receipt } = await Actions.rewards.startSync(client, { - * amount: 100000000000000000000n, - * seconds: 86400, - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The stream ID, funder, amount, duration, and transaction receipt. - */ -export async function startSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: startSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await start.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = start.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace start { - export type Args = { - /** The amount of tokens to distribute (must be > 0) */ - amount: bigint - /** The TIP20 token address */ - token: Address - } - - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: Parameters, - ): Promise> { - const { amount, token, ...rest } = parameters - const call = start.call({ amount, token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `start` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const hash = await client.sendTransaction({ - * calls: [actions.rewards.start.call({ - * amount: 100000000000000000000n, - * seconds: 86400, - * token: '0x20c0000000000000000000000000000000000001', - * })], - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { amount, token } = args - return defineCall({ - address: token, - abi: Abis.tip20, - args: [amount, 0], - functionName: 'startReward', - }) - } - - /** - * Extracts the `RewardScheduled` event from logs. - * - * @param logs - The logs. - * @returns The `RewardScheduled` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'RewardScheduled', - strict: true, - }) - if (!log) throw new Error('`RewardScheduled` event not found.') - return log - } -} - -export declare namespace startSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & start.Args - - export type ReturnValue = { - /** The total amount allocated to the stream */ - amount: bigint - /** The duration of the stream in seconds (0 for immediate distributions) */ - durationSeconds: number - /** The address that funded the stream */ - funder: Address - /** The unique stream ID (0 for immediate distributions, >0 for streaming distributions) */ - id: bigint - /** The transaction receipt */ - receipt: Awaited> - } - - export type ErrorType = start.ErrorType -} - -/** - * Watches for reward scheduled events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = Actions.reward.watchRewardScheduled(client, { - * token: '0x20c0000000000000000000000000000000000001', - * onRewardScheduled: (args, log) => { - * console.log('Reward scheduled:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchRewardScheduled< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchRewardScheduled.Parameters, -) { - const { onRewardScheduled, token, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: token, - abi: Abis.tip20, - eventName: 'RewardScheduled', - onLogs: (logs) => { - for (const log of logs) onRewardScheduled(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchRewardScheduled { - export type Args = GetEventArgs< - typeof Abis.tip20, - 'RewardScheduled', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when rewards are scheduled. */ - onRewardScheduled: (args: Args, log: Log) => void - /** The TIP20 token address */ - token: Address - } - - export type ReturnValue = WatchContractEventReturnType -} - -/** - * Watches for reward recipient set events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = Actions.reward.watchRewardRecipientSet(client, { - * token: '0x20c0000000000000000000000000000000000001', - * onRewardRecipientSet: (args, log) => { - * console.log('Reward recipient set:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchRewardRecipientSet< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchRewardRecipientSet.Parameters, -) { - const { onRewardRecipientSet, token, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: token, - abi: Abis.tip20, - eventName: 'RewardRecipientSet', - onLogs: (logs) => { - for (const log of logs) onRewardRecipientSet(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchRewardRecipientSet { - export type Args = GetEventArgs< - typeof Abis.tip20, - 'RewardRecipientSet', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a reward recipient is set. */ - onRewardRecipientSet: (args: Args, log: Log) => void - /** The TIP20 token address */ - token: Address - } - - export type ReturnValue = WatchContractEventReturnType -} diff --git a/src/viem/Actions/token.test.ts b/src/viem/Actions/token.test.ts deleted file mode 100644 index 641faaba..00000000 --- a/src/viem/Actions/token.test.ts +++ /dev/null @@ -1,3029 +0,0 @@ -import { setTimeout } from 'node:timers/promises' -import { Hex } from 'ox' -import { TokenRole } from 'ox/tempo' -import { Abis, Addresses, TokenIds } from 'tempo.ts/viem' -import { parseUnits } from 'viem' -import { getCode, writeContractSync } from 'viem/actions' -import { beforeAll, describe, expect, test } from 'vitest' -import { addresses, rpcUrl } from '../../../test/config.js' -import { accounts, clientWithAccount } from '../../../test/viem/config.js' -import * as actions from './index.js' - -const account = accounts[0] -const account2 = accounts[1] -const account3 = accounts[2] - -describe('approve', () => { - test('default', async () => { - { - // approve - const { receipt, ...result } = await actions.token.approveSync( - clientWithAccount, - { - spender: account2.address, - amount: parseUnits('100', 6), - token: addresses.alphaUsd, - }, - ) - expect(receipt).toBeDefined() - expect(result).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - } - - { - // check allowance - const allowance = await actions.token.getAllowance(clientWithAccount, { - spender: account2.address, - token: addresses.alphaUsd, - }) - expect(allowance).toBe(parseUnits('100', 6)) - } - - // transfer tokens for gas - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - // transfer tokens from approved account - await actions.token.transferSync(clientWithAccount, { - amount: parseUnits('50', 6), - account: account2, - from: account.address, - to: '0x0000000000000000000000000000000000000001', - token: addresses.alphaUsd, - }) - - { - // verify updated allowance - const allowance = await actions.token.getAllowance(clientWithAccount, { - spender: account2.address, - token: addresses.alphaUsd, - }) - expect(allowance).toBe(parseUnits('50', 6)) - } - - // verify balance - const balance = await actions.token.getBalance(clientWithAccount, { - account: '0x0000000000000000000000000000000000000001', - token: addresses.alphaUsd, - }) - expect(balance).toBe(parseUnits('50', 6)) - }) - - test('behavior: token address', async () => { - const balanceBefore = await actions.token.getBalance(clientWithAccount, { - account: '0x0000000000000000000000000000000000000001', - token: addresses.alphaUsd, - }) - - { - // approve - const { receipt, ...result } = await actions.token.approveSync( - clientWithAccount, - { - amount: parseUnits('100', 6), - token: addresses.alphaUsd, - spender: account2.address, - }, - ) - expect(receipt).toBeDefined() - expect(result).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - } - - { - // check allowance - const allowance = await actions.token.getAllowance(clientWithAccount, { - token: addresses.alphaUsd, - spender: account2.address, - }) - expect(allowance).toBe(parseUnits('100', 6)) - } - - // transfer tokens for gas - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - // transfer tokens from approved account - await actions.token.transferSync(clientWithAccount, { - amount: parseUnits('50', 6), - account: account2, - from: account.address, - to: '0x0000000000000000000000000000000000000001', - token: addresses.alphaUsd, - }) - - { - // verify updated allowance - const allowance = await actions.token.getAllowance(clientWithAccount, { - spender: account2.address, - token: addresses.alphaUsd, - }) - expect(allowance).toBe(parseUnits('50', 6)) - } - - // verify balance - const balance = await actions.token.getBalance(clientWithAccount, { - account: '0x0000000000000000000000000000000000000001', - token: addresses.alphaUsd, - }) - expect(balance).toBe(balanceBefore + parseUnits('50', 6)) - }) - - test('behavior: token address', async () => { - const balanceBefore = await actions.token.getBalance(clientWithAccount, { - account: '0x0000000000000000000000000000000000000001', - token: addresses.alphaUsd, - }) - - { - // approve - const { receipt, ...result } = await actions.token.approveSync( - clientWithAccount, - { - amount: parseUnits('100', 6), - token: addresses.alphaUsd, - spender: account2.address, - }, - ) - expect(receipt).toBeDefined() - expect(result).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - } - - { - // check allowance - const allowance = await actions.token.getAllowance(clientWithAccount, { - token: addresses.alphaUsd, - spender: account2.address, - }) - expect(allowance).toBe(parseUnits('100', 6)) - } - - // transfer tokens for gas - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - // transfer tokens from approved account - await actions.token.transferSync(clientWithAccount, { - amount: parseUnits('50', 6), - account: account2, - from: account.address, - to: '0x0000000000000000000000000000000000000001', - token: addresses.alphaUsd, - }) - - { - // verify updated allowance - const allowance = await actions.token.getAllowance(clientWithAccount, { - spender: account2.address, - token: addresses.alphaUsd, - }) - expect(allowance).toBe(parseUnits('50', 6)) - } - - // verify balance - const balance = await actions.token.getBalance(clientWithAccount, { - account: '0x0000000000000000000000000000000000000001', - token: addresses.alphaUsd, - }) - expect(balance).toBe(balanceBefore + parseUnits('50', 6)) - }) -}) - -describe('create', () => { - test('default', async () => { - const { receipt, token, tokenId, ...result } = - await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Test USD', - symbol: 'TUSD', - }) - - expect(result).toMatchInlineSnapshot(` - { - "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "currency": "USD", - "name": "Test USD", - "quoteToken": "0x20C0000000000000000000000000000000000000", - "symbol": "TUSD", - } - `) - expect(token).toBeDefined() - expect(tokenId).toBeDefined() - expect(receipt).toBeDefined() - - const code = await getCode(clientWithAccount, { - address: token, - }) - expect(code).toBe('0xef') - }) -}) - -describe('getAllowance', () => { - test('default', async () => { - // First, approve some allowance - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'approve', - args: [account2.address, parseUnits('50', 6)], - }) - - { - // Test with default token - const allowance = await actions.token.getAllowance(clientWithAccount, { - spender: account2.address, - token: addresses.alphaUsd, - }) - expect(allowance).toBe(parseUnits('50', 6)) - } - - { - // Test with token address - const allowance = await actions.token.getAllowance(clientWithAccount, { - token: addresses.alphaUsd, - spender: account2.address, - }) - - expect(allowance).toBe(parseUnits('50', 6)) - } - - { - // Test with token ID - const allowance = await actions.token.getAllowance(clientWithAccount, { - token: addresses.alphaUsd, - spender: account2.address, - }) - - expect(allowance).toBe(parseUnits('50', 6)) - } - }) -}) - -describe('getBalance', () => { - test('default', async () => { - { - // Test with token address - const balance = await actions.token.getBalance(clientWithAccount, { - token: addresses.alphaUsd, - }) - - expect(balance).toBeGreaterThan(0n) - } - - { - // Test with token ID & different account - const balance = await actions.token.getBalance(clientWithAccount, { - token: addresses.alphaUsd, - account: Hex.random(20), - }) - - expect(balance).toBe(0n) - } - }) -}) - -describe('getMetadata', () => { - test('default', async () => { - const metadata = await actions.token.getMetadata(clientWithAccount, { - token: addresses.alphaUsd, - }) - - expect(metadata).toMatchInlineSnapshot(` - { - "currency": "USD", - "decimals": 6, - "name": "AlphaUSD", - "paused": false, - "quoteToken": "0x20C0000000000000000000000000000000000000", - "supplyCap": 340282366920938463463374607431768211455n, - "symbol": "AlphaUSD", - "totalSupply": 202914184810805067765n, - "transferPolicyId": 1n, - } - `) - }) - - test('behavior: custom token (address)', async () => { - const { token } = await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Test USD', - symbol: 'TUSD', - }) - - const metadata = await actions.token.getMetadata(clientWithAccount, { - token, - }) - - expect(metadata).toMatchInlineSnapshot(` - { - "currency": "USD", - "decimals": 6, - "name": "Test USD", - "paused": false, - "quoteToken": "0x20C0000000000000000000000000000000000000", - "supplyCap": 340282366920938463463374607431768211455n, - "symbol": "TUSD", - "totalSupply": 0n, - "transferPolicyId": 1n, - } - `) - }) - - test('behavior: quote token', async () => { - { - const metadata = await actions.token.getMetadata(clientWithAccount, { - token: TokenIds.pathUsd, - }) - - expect(metadata).toMatchInlineSnapshot(` - { - "currency": "USD", - "decimals": 6, - "name": "pathUSD", - "symbol": "pathUSD", - "totalSupply": 184467440737095516150n, - } - `) - } - - { - const metadata = await actions.token.getMetadata(clientWithAccount, { - token: Addresses.pathUsd, - }) - - expect(metadata).toMatchInlineSnapshot(` - { - "currency": "USD", - "decimals": 6, - "name": "pathUSD", - "symbol": "pathUSD", - "totalSupply": 184467440737095516150n, - } - `) - } - }) - - test('behavior: custom token (id)', async () => { - const token = await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Test USD', - symbol: 'TUSD', - }) - - const metadata = await actions.token.getMetadata(clientWithAccount, { - token: token.tokenId, - }) - - expect(metadata).toMatchInlineSnapshot(` - { - "currency": "USD", - "decimals": 6, - "name": "Test USD", - "paused": false, - "quoteToken": "0x20C0000000000000000000000000000000000000", - "supplyCap": 340282366920938463463374607431768211455n, - "symbol": "TUSD", - "totalSupply": 0n, - "transferPolicyId": 1n, - } - `) - }) -}) - -describe('mint', () => { - test('default', async () => { - // Create a new token where we're the admin - const { token } = await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Mintable Token', - symbol: 'MINT', - }) - - // Grant issuer role - await actions.token.grantRolesSync(clientWithAccount, { - token, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - // Check initial balance - const balanceBefore = await actions.token.getBalance(clientWithAccount, { - token, - account: account2.address, - }) - expect(balanceBefore).toBe(0n) - - // Mint tokens - const { receipt: mintReceipt, ...mintResult } = - await actions.token.mintSync(clientWithAccount, { - token, - to: account2.address, - amount: parseUnits('1000', 6), - }) - expect(mintReceipt).toBeDefined() - expect(mintResult).toMatchInlineSnapshot(` - { - "amount": 1000000000n, - "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - - // Check balance after mint - const balanceAfter = await actions.token.getBalance(clientWithAccount, { - token, - account: account2.address, - }) - expect(balanceAfter).toBe(parseUnits('1000', 6)) - - // Check total supply - const metadata = await actions.token.getMetadata(clientWithAccount, { - token, - }) - expect(metadata.totalSupply).toBe(parseUnits('1000', 6)) - }) - - // TODO: fix - test.skip('with memo', async () => { - // Create a new token - const { token } = await actions.token.createSync(clientWithAccount, { - admin: clientWithAccount.account, - currency: 'USD', - name: 'Mintable Token 2', - symbol: 'MINT2', - }) - - // Grant issuer role - await actions.token.grantRolesSync(clientWithAccount, { - token, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - // Mint tokens with memo - const { receipt: mintMemoReceipt, ...mintMemoResult } = - await actions.token.mintSync(clientWithAccount, { - token, - to: account2.address, - amount: parseUnits('500', 6), - memo: Hex.fromString('test'), - }) - expect(mintMemoReceipt.status).toBe('success') - expect(mintMemoResult).toMatchInlineSnapshot(` - { - "amount": 500000000000000000000n, - "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - - // Verify balance - const balance = await actions.token.getBalance(clientWithAccount, { - token, - account: account2.address, - }) - expect(balance).toBe(parseUnits('500', 6)) - }) -}) - -describe('transfer', () => { - test('default', async () => { - // Get initial balances - const senderBalanceBefore = await actions.token.getBalance( - clientWithAccount, - { - account: account.address, - token: addresses.alphaUsd, - }, - ) - const receiverBalanceBefore = await actions.token.getBalance( - clientWithAccount, - { - account: account2.address, - token: addresses.alphaUsd, - }, - ) - - // Transfer tokens - const { receipt: transferReceipt, ...transferResult } = - await actions.token.transferSync(clientWithAccount, { - to: account2.address, - amount: parseUnits('10', 6), - token: addresses.alphaUsd, - }) - expect(transferReceipt).toBeDefined() - expect(transferResult).toMatchInlineSnapshot(` - { - "amount": 10000000n, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - - // Verify balances - const senderBalanceAfter = await actions.token.getBalance( - clientWithAccount, - { - account: account.address, - token: addresses.alphaUsd, - }, - ) - const receiverBalanceAfter = await actions.token.getBalance( - clientWithAccount, - { - account: account2.address, - token: addresses.alphaUsd, - }, - ) - - expect(senderBalanceAfter - senderBalanceBefore).toBeLessThan( - parseUnits('10', 6), - ) - expect(receiverBalanceAfter - receiverBalanceBefore).toBe( - parseUnits('10', 6), - ) - }) - - test('behavior: with custom token', async () => { - // Create a new token - const { token } = await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Transfer Token', - symbol: 'XFER', - }) - - // Grant issuer role and mint tokens - await actions.token.grantRolesSync(clientWithAccount, { - token, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - await actions.token.mintSync(clientWithAccount, { - token, - to: clientWithAccount.account.address, - amount: parseUnits('1000', 6), - }) - - // Transfer custom tokens - await actions.token.transferSync(clientWithAccount, { - token, - to: account2.address, - amount: parseUnits('100', 6), - }) - - // Verify balance - const balance = await actions.token.getBalance(clientWithAccount, { - token, - account: account2.address, - }) - expect(balance).toBe(parseUnits('100', 6)) - }) - - test('behavior: with memo', async () => { - const memo = Hex.fromString('Payment for services') - - const { receipt: transferMemoReceipt, ...transferMemoResult } = - await actions.token.transferSync(clientWithAccount, { - to: account2.address, - amount: parseUnits('5', 6), - memo, - token: addresses.alphaUsd, - }) - - expect(transferMemoReceipt.status).toBe('success') - expect(transferMemoResult).toMatchInlineSnapshot(` - { - "amount": 5000000n, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - }) - - test('behavior: from another account (transferFrom)', async () => { - // First approve account2 to spend tokens - await actions.token.approveSync(clientWithAccount, { - spender: account2.address, - amount: parseUnits('50', 6), - token: addresses.alphaUsd, - }) - - // Transfer tokens for gas - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - // Get initial balance - const balanceBefore = await actions.token.getBalance(clientWithAccount, { - account: account3.address, - token: addresses.alphaUsd, - }) - - // Account2 transfers from account to account3 - await actions.token.transferSync(clientWithAccount, { - account: account2, - from: account.address, - to: account3.address, - amount: parseUnits('25', 6), - token: addresses.alphaUsd, - }) - - // Verify balance - const balanceAfter = await actions.token.getBalance(clientWithAccount, { - account: account3.address, - token: addresses.alphaUsd, - }) - expect(balanceAfter - balanceBefore).toBe(parseUnits('25', 6)) - - // Verify allowance was reduced - const allowance = await actions.token.getAllowance(clientWithAccount, { - spender: account2.address, - token: addresses.alphaUsd, - }) - expect(allowance).toBe(parseUnits('25', 6)) - }) -}) - -describe('burn', () => { - test('default', async () => { - // Create a new token where we have issuer role - const { token } = await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Burnable Token', - symbol: 'BURN', - }) - - // Grant issuer role - await actions.token.grantRolesSync(clientWithAccount, { - token, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - // Mint some tokens - await actions.token.mintSync(clientWithAccount, { - token, - to: clientWithAccount.account.address, - amount: parseUnits('1000', 6), - }) - - // Check balance before burn - const balanceBefore = await actions.token.getBalance(clientWithAccount, { - token, - }) - expect(balanceBefore).toBe(parseUnits('1000', 6)) - - // Check total supply before - const metadataBefore = await actions.token.getMetadata(clientWithAccount, { - token, - }) - expect(metadataBefore.totalSupply).toBe(parseUnits('1000', 6)) - - // Burn tokens - const { receipt, ...result } = await actions.token.burnSync( - clientWithAccount, - { - token, - amount: parseUnits('100', 6), - }, - ) - expect(receipt).toBeDefined() - expect(result).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - // Check balance after burn - const balanceAfter = await actions.token.getBalance(clientWithAccount, { - token, - }) - expect(balanceAfter).toBe(parseUnits('900', 6)) - - // Check total supply after - const metadataAfter = await actions.token.getMetadata(clientWithAccount, { - token, - }) - expect(metadataAfter.totalSupply).toBe(parseUnits('900', 6)) - }) - - test('behavior: requires issuer role', async () => { - // Create a new token - const { token } = await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Restricted Burn Token', - symbol: 'RBURN', - }) - - // Grant issuer role to account2 (not us) - await actions.token.grantRolesSync(clientWithAccount, { - token, - roles: ['issuer'], - to: account2.address, - }) - - // Transfer gas to account2 - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - await actions.token.mintSync(clientWithAccount, { - account: account2, - feeToken: addresses.alphaUsd, - token, - to: clientWithAccount.account.address, - amount: parseUnits('100', 6), - }) - - // Try to burn without issuer role - should fail - await expect( - actions.token.burnSync(clientWithAccount, { - token, - amount: parseUnits('10', 6), - }), - ).rejects.toThrow() - }) -}) - -describe.todo('burnBlockedToken') - -describe.todo('changeTokenTransferPolicy') - -describe('pause', () => { - test('default', async () => { - // Create a new token - const { token } = await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Pausable Token', - symbol: 'PAUSE', - }) - - // Grant pause role - await actions.token.grantRolesSync(clientWithAccount, { - token, - roles: ['pause'], - to: clientWithAccount.account.address, - }) - - // Grant issuer role and mint tokens - await actions.token.grantRolesSync(clientWithAccount, { - token, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - await actions.token.mintSync(clientWithAccount, { - token, - to: account2.address, - amount: parseUnits('1000', 6), - }) - - // Verify token is not paused - let metadata = await actions.token.getMetadata(clientWithAccount, { - token, - }) - expect(metadata.paused).toBe(false) - - // Transfer gas - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - await actions.token.transferSync(clientWithAccount, { - account: account2, - token, - to: account3.address, - amount: parseUnits('100', 6), - }) - - // Pause the token - const { receipt: pauseReceipt, ...pauseResult } = - await actions.token.pauseSync(clientWithAccount, { - token, - }) - expect(pauseReceipt).toBeDefined() - expect(pauseResult).toMatchInlineSnapshot(` - { - "isPaused": true, - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - // Verify token is paused - metadata = await actions.token.getMetadata(clientWithAccount, { - token, - }) - expect(metadata.paused).toBe(true) - - // Transfers should now fail - await expect( - actions.token.transferSync(clientWithAccount, { - account: account2, - token, - to: account3.address, - amount: parseUnits('100', 6), - }), - ).rejects.toThrow() - }) - - test('behavior: requires pause role', async () => { - // Create a new token - const { token } = await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Restricted Pause Token', - symbol: 'RPAUSE', - }) - - // Try to pause without pause role - should fail - await expect( - actions.token.pauseSync(clientWithAccount, { - token, - }), - ).rejects.toThrow() - - // Grant pause role to account2 - await actions.token.grantRolesSync(clientWithAccount, { - token, - roles: ['pause'], - to: account2.address, - }) - - // Transfer gas to account2 - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - await actions.token.pauseSync(clientWithAccount, { - account: account2, - feeToken: addresses.alphaUsd, - token, - }) - - // Verify token is paused - const metadata = await actions.token.getMetadata(clientWithAccount, { - token, - }) - expect(metadata.paused).toBe(true) - }) - - test('behavior: cannot pause already paused token', async () => { - // Create a new token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Double Pause Token', - symbol: 'DPAUSE', - }, - ) - - // Grant pause role - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['pause'], - to: clientWithAccount.account.address, - }) - - // Pause the token - await actions.token.pauseSync(clientWithAccount, { - token: address, - }) - - // Try to pause again - implementation may vary, but typically this succeeds without error - const { receipt: doublePauseReceipt, ...doublePauseResult } = - await actions.token.pauseSync(clientWithAccount, { - token: address, - }) - expect(doublePauseReceipt.status).toBe('success') - expect(doublePauseResult).toMatchInlineSnapshot(` - { - "isPaused": true, - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - }) -}) - -describe('unpause', () => { - test('default', async () => { - // Create a new token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Unpausable Token', - symbol: 'UNPAUSE', - }, - ) - - // Grant pause and unpause roles - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['pause'], - to: clientWithAccount.account.address, - }) - - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['unpause'], - to: clientWithAccount.account.address, - }) - - // Grant issuer role and mint tokens - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - await actions.token.mintSync(clientWithAccount, { - token: address, - to: account2.address, - amount: parseUnits('1000', 6), - }) - - // First pause the token - await actions.token.pauseSync(clientWithAccount, { - token: address, - }) - - // Verify token is paused - let metadata = await actions.token.getMetadata(clientWithAccount, { - token: address, - }) - expect(metadata.paused).toBe(true) - - // Transfer gas to account2 - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - // Verify transfers fail when paused - await expect( - actions.token.transferSync(clientWithAccount, { - account: account2, - token: address, - to: account3.address, - amount: parseUnits('100', 6), - }), - ).rejects.toThrow() - - // Unpause the token - const { receipt: unpauseReceipt, ...unpauseResult } = - await actions.token.unpauseSync(clientWithAccount, { - token: address, - }) - expect(unpauseReceipt).toBeDefined() - expect(unpauseResult).toMatchInlineSnapshot(` - { - "isPaused": false, - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - // Verify token is unpaused - metadata = await actions.token.getMetadata(clientWithAccount, { - token: address, - }) - expect(metadata.paused).toBe(false) - - // Transfers should work again - await actions.token.transferSync(clientWithAccount, { - account: account2, - token: address, - to: account3.address, - amount: parseUnits('100', 6), - }) - - const balance = await actions.token.getBalance(clientWithAccount, { - token: address, - account: account3.address, - }) - expect(balance).toBe(parseUnits('100', 6)) - }) - - test('behavior: requires unpause role', async () => { - // Create a new token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Restricted Unpause Token', - symbol: 'RUNPAUSE', - }, - ) - - // Grant pause role and pause the token - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['pause'], - to: clientWithAccount.account.address, - }) - - await actions.token.pauseSync(clientWithAccount, { - token: address, - }) - - // Try to unpause without unpause role - should fail - await expect( - actions.token.unpauseSync(clientWithAccount, { - token: address, - }), - ).rejects.toThrow() - - // Grant unpause role to account2 - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['unpause'], - to: account2.address, - }) - - // Transfer gas to account2 - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - // Now account2 should be able to unpause - await actions.token.unpauseSync(clientWithAccount, { - account: account2, - feeToken: addresses.alphaUsd, - token: address, - }) - - // Verify token is unpaused - const metadata = await actions.token.getMetadata(clientWithAccount, { - token: address, - }) - expect(metadata.paused).toBe(false) - }) - - test('behavior: different roles for pause and unpause', async () => { - // Create a new token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Split Role Token', - symbol: 'SPLIT', - }, - ) - - // Grant pause role to account2 - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['pause'], - to: account2.address, - }) - - // Grant unpause role to account3 - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['unpause'], - to: account3.address, - }) - - // Transfer gas to both accounts - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account3.address, parseUnits('1', 6)], - }) - - // Account2 can pause - await actions.token.pauseSync(clientWithAccount, { - account: account2, - feeToken: addresses.alphaUsd, - token: address, - }) - - // Account2 cannot unpause - await expect( - actions.token.unpauseSync(clientWithAccount, { - account: account2, - token: address, - }), - ).rejects.toThrow() - - // Account3 can unpause - await actions.token.unpauseSync(clientWithAccount, { - account: account3, - feeToken: addresses.alphaUsd, - token: address, - }) - - // Verify token is unpaused - const metadata = await actions.token.getMetadata(clientWithAccount, { - token: address, - }) - expect(metadata.paused).toBe(false) - }) -}) - -describe('prepareUpdateQuoteToken', () => { - test('default', async () => { - // Create two tokens - one to be the new quote token - const { token: quoteTokenAddress } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Quote Token', - symbol: 'LINK', - }, - ) - - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Main Token', - symbol: 'MAIN', - }, - ) - - // Update quote token - const { - receipt: updateReceipt, - nextQuoteToken, - ...updateResult - } = await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, { - token: address, - quoteToken: quoteTokenAddress, - }) - - expect(updateReceipt).toBeDefined() - expect(updateResult).toMatchInlineSnapshot(` - { - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - // Verify the event was emitted with correct quote token - expect(nextQuoteToken).toBe(quoteTokenAddress) - }) - - test('behavior: requires admin role', async () => { - // Create quote token - const { token: quoteTokenAddress } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Quote Token 2', - symbol: 'LINK2', - }, - ) - - // Create main token where clientWithAccount.account is admin - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Restricted Token', - symbol: 'RESTR', - }, - ) - - // Transfer gas to account2 - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - // Try to update quote token from account2 (not admin) - should fail - await expect( - actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, { - account: account2, - token: address, - quoteToken: quoteTokenAddress, - }), - ).rejects.toThrow() - }) - - test('behavior: with token ID', async () => { - // Create quote token - const { token: quoteTokenAddress } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Quote Token 3', - symbol: 'LINK3', - }, - ) - - // Create main token using token ID - const { tokenId: mainTokenId } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Main Token ID', - symbol: 'MAINID', - }, - ) - - // Update quote token using token ID for main token, address for quote token - const { - receipt: updateReceipt, - nextQuoteToken, - ...updateResult - } = await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, { - token: mainTokenId, - quoteToken: quoteTokenAddress, - }) - - expect(updateResult).toMatchInlineSnapshot(` - { - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - expect(nextQuoteToken).toBe(quoteTokenAddress) - expect(updateReceipt.status).toBe('success') - }) -}) - -describe('finalizeUpdateQuoteToken', () => { - test('default', async () => { - // Create quote token - const { token: quoteTokenAddress } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Quote Token', - symbol: 'LINK', - }, - ) - - // Create main token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Main Token', - symbol: 'MAIN', - }, - ) - - // Prepare update quote token (step 1) - await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, { - token: address, - quoteToken: quoteTokenAddress, - }) - - // Finalize the update (step 2) - const { - receipt: finalizeReceipt, - newQuoteToken, - ...finalizeResult - } = await actions.token.updateQuoteTokenSync(clientWithAccount, { - token: address, - }) - - expect(finalizeReceipt).toBeDefined() - expect(finalizeResult).toMatchInlineSnapshot(` - { - "updater": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - // Verify the quote token was updated - expect(newQuoteToken).toBe(quoteTokenAddress) - - // Verify it's reflected in metadata - const metadata = await actions.token.getMetadata(clientWithAccount, { - token: address, - }) - expect(metadata.quoteToken).toBe(quoteTokenAddress) - }) - - test('behavior: requires admin role', async () => { - // Create quote token - const { token: quoteTokenAddress } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Quote Token 2', - symbol: 'LINK2', - }, - ) - - // Create main token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Restricted Token', - symbol: 'RESTR', - }, - ) - - // Update quote token as admin - await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, { - token: address, - quoteToken: quoteTokenAddress, - }) - - // Transfer gas to account2 - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - // Try to finalize as non-admin - should fail - await expect( - actions.token.updateQuoteTokenSync(clientWithAccount, { - account: account2, - token: address, - }), - ).rejects.toThrow() - }) - - test('behavior: prevents circular references', async () => { - // Create token B - const { token: tokenBAddress } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Token B', - symbol: 'TKB', - }, - ) - - // Create token A that links to token B - const { token: tokenAAddress } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Token A', - symbol: 'TKA', - quoteToken: tokenBAddress, - }, - ) - - // Try to make token B link to token A (would create A -> B -> A loop) - await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, { - token: tokenBAddress, - quoteToken: tokenAAddress, - }) - - // Finalize should fail due to circular reference detection - await expect( - actions.token.updateQuoteTokenSync(clientWithAccount, { - token: tokenBAddress, - }), - ).rejects.toThrow() - }) -}) - -describe.todo('setTokenSupplyCap') - -describe('hasRole', () => { - test('default', async () => { - // Create a new token where we're the admin - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'HasRole Test Token', - symbol: 'HRTEST', - }, - ) - - // Client account should have defaultAdmin role on the new token - const hasDefaultAdminRole = await actions.token.hasRole(clientWithAccount, { - token: address, - role: 'defaultAdmin', - }) - expect(hasDefaultAdminRole).toBe(true) - - // Client account should not have issuer role initially on the new token - const hasIssuerRole = await actions.token.hasRole(clientWithAccount, { - token: address, - role: 'issuer', - }) - expect(hasIssuerRole).toBe(false) - - // Grant issuer role - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - // Now should have issuer role - const hasIssuerRoleAfterGrant = await actions.token.hasRole( - clientWithAccount, - { - token: address, - role: 'issuer', - }, - ) - expect(hasIssuerRoleAfterGrant).toBe(true) - }) - - test('behavior: check other account', async () => { - // Create a new token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'HasRole Other Account', - symbol: 'HROAC', - }, - ) - - // Account2 should not have issuer role - const hasIssuerBefore = await actions.token.hasRole(clientWithAccount, { - token: address, - account: account2.address, - role: 'issuer', - }) - expect(hasIssuerBefore).toBe(false) - - // Grant issuer role to account2 - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: account2.address, - }) - - // Account2 should now have issuer role - const hasIssuerAfter = await actions.token.hasRole(clientWithAccount, { - token: address, - account: account2.address, - role: 'issuer', - }) - expect(hasIssuerAfter).toBe(true) - - // Account3 should still not have issuer role - const account3HasIssuer = await actions.token.hasRole(clientWithAccount, { - token: address, - account: account3.address, - role: 'issuer', - }) - expect(account3HasIssuer).toBe(false) - }) - - test('behavior: multiple roles', async () => { - // Create a new token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'HasRole Multiple', - symbol: 'HRMULTI', - }, - ) - - // Grant multiple roles to account2 - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer', 'pause'], - to: account2.address, - }) - - // Check issuer role - const hasIssuer = await actions.token.hasRole(clientWithAccount, { - token: address, - account: account2.address, - role: 'issuer', - }) - expect(hasIssuer).toBe(true) - - // Check pause role - const hasPause = await actions.token.hasRole(clientWithAccount, { - token: address, - account: account2.address, - role: 'pause', - }) - expect(hasPause).toBe(true) - - // Check unpause role (not granted) - const hasUnpause = await actions.token.hasRole(clientWithAccount, { - token: address, - account: account2.address, - role: 'unpause', - }) - expect(hasUnpause).toBe(false) - }) - - test('behavior: after revoke', async () => { - // Create a new token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'HasRole Revoke', - symbol: 'HRREV', - }, - ) - - // Grant issuer role to account2 - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: account2.address, - }) - - // Verify has role - const hasRoleBefore = await actions.token.hasRole(clientWithAccount, { - token: address, - account: account2.address, - role: 'issuer', - }) - expect(hasRoleBefore).toBe(true) - - // Revoke the role - await actions.token.revokeRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - from: account2.address, - }) - - // Verify no longer has role - const hasRoleAfter = await actions.token.hasRole(clientWithAccount, { - token: address, - account: account2.address, - role: 'issuer', - }) - expect(hasRoleAfter).toBe(false) - }) - - test('behavior: with token ID', async () => { - // Create a new token - const { token: address, tokenId } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'HasRole Token ID', - symbol: 'HRTID', - }, - ) - - // Grant issuer role - await actions.token.grantRolesSync(clientWithAccount, { - token: tokenId, - roles: ['issuer'], - to: account2.address, - }) - - // Check using token ID - const hasRole = await actions.token.hasRole(clientWithAccount, { - token: tokenId, - account: account2.address, - role: 'issuer', - }) - expect(hasRole).toBe(true) - - // Verify same result with address - const hasRoleWithAddress = await actions.token.hasRole(clientWithAccount, { - token: address, - account: account2.address, - role: 'issuer', - }) - expect(hasRoleWithAddress).toBe(true) - }) -}) - -describe('getRoleAdmin', () => { - test('default', async () => { - // Create a new token where we're the admin - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'GetRoleAdmin Test Token', - symbol: 'GRATEST', - }, - ) - - // Get admin role for issuer role (should be defaultAdmin) - const issuerAdminRole = await actions.token.getRoleAdmin( - clientWithAccount, - { - token: address, - role: 'issuer', - }, - ) - expect(issuerAdminRole).toBe( - '0x0000000000000000000000000000000000000000000000000000000000000000', - ) - - // Get admin role for pause role (should be defaultAdmin) - const pauseAdminRole = await actions.token.getRoleAdmin(clientWithAccount, { - token: address, - role: 'pause', - }) - expect(pauseAdminRole).toBe( - '0x0000000000000000000000000000000000000000000000000000000000000000', - ) - - // Get admin role for unpause role (should be defaultAdmin) - const unpauseAdminRole = await actions.token.getRoleAdmin( - clientWithAccount, - { - token: address, - role: 'unpause', - }, - ) - expect(unpauseAdminRole).toBe( - '0x0000000000000000000000000000000000000000000000000000000000000000', - ) - }) - - test('behavior: after setting role admin', async () => { - // Create a new token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'GetRoleAdmin After Set', - symbol: 'GRASET', - }, - ) - - // Get initial admin role for issuer - const initialAdminRole = await actions.token.getRoleAdmin( - clientWithAccount, - { - token: address, - role: 'issuer', - }, - ) - expect(initialAdminRole).toBe( - '0x0000000000000000000000000000000000000000000000000000000000000000', - ) - - // Set pause as admin role for issuer - await actions.token.setRoleAdminSync(clientWithAccount, { - token: address, - role: 'issuer', - adminRole: 'pause', - }) - - // Get updated admin role for issuer - const updatedAdminRole = await actions.token.getRoleAdmin( - clientWithAccount, - { - token: address, - role: 'issuer', - }, - ) - expect(updatedAdminRole).toBe(TokenRole.serialize('pause')) - }) - - test('behavior: with token ID', async () => { - // Create a new token - const { token: address, tokenId } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'GetRoleAdmin Token ID', - symbol: 'GRATID', - }, - ) - - // Get admin role using token ID - const adminRoleWithId = await actions.token.getRoleAdmin( - clientWithAccount, - { - token: tokenId, - role: 'issuer', - }, - ) - expect(adminRoleWithId).toBe( - '0x0000000000000000000000000000000000000000000000000000000000000000', - ) - - // Get admin role using address - const adminRoleWithAddress = await actions.token.getRoleAdmin( - clientWithAccount, - { - token: address, - role: 'issuer', - }, - ) - expect(adminRoleWithAddress).toBe(adminRoleWithId) - }) - - test('behavior: defaultAdmin role admin', async () => { - // Create a new token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'GetRoleAdmin DefaultAdmin', - symbol: 'GRADMIN', - }, - ) - - // Get admin role for defaultAdmin role (should be itself - 0x00) - const defaultAdminAdminRole = await actions.token.getRoleAdmin( - clientWithAccount, - { - token: address, - role: 'defaultAdmin', - }, - ) - expect(defaultAdminAdminRole).toBe( - '0x0000000000000000000000000000000000000000000000000000000000000000', - ) - }) -}) - -describe('grantRoles', () => { - test('default', async () => { - // Create a new token where we're the admin - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - admin: clientWithAccount.account, - currency: 'USD', - name: 'Test Token', - symbol: 'TEST', - }, - ) - - // Grant issuer role to account2 - const { receipt: grantReceipt, value: grantValue } = - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: account2.address, - }) - - expect(grantReceipt.status).toBe('success') - expect(grantValue).toHaveLength(1) - const { role, ...restGrant } = grantValue[0]! - expect(restGrant).toMatchInlineSnapshot(` - { - "account": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - "hasRole": true, - "sender": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - expect(role).toBeDefined() - }) -}) - -describe('revokeTokenRole', async () => { - test('default', async () => { - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - admin: clientWithAccount.account, - currency: 'USD', - name: 'Test Token 2', - symbol: 'TEST2', - }, - ) - - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: account2.address, - }) - - const { receipt: revokeReceipt, value: revokeValue } = - await actions.token.revokeRolesSync(clientWithAccount, { - from: account2.address, - token: address, - roles: ['issuer'], - }) - - expect(revokeReceipt.status).toBe('success') - expect(revokeValue).toHaveLength(1) - const { role, ...restRevoke } = revokeValue[0]! - expect(restRevoke).toMatchInlineSnapshot(` - { - "account": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - "hasRole": false, - "sender": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - expect(role).toBeDefined() - }) -}) - -describe('renounceTokenRole', async () => { - test('default', async () => { - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - admin: clientWithAccount.account, - currency: 'USD', - name: 'Test Token 3', - symbol: 'TEST3', - }, - ) - - const { receipt: grantReceipt } = await actions.token.grantRolesSync( - clientWithAccount, - { - token: address, - roles: ['issuer'], - to: clientWithAccount.account.address, - }, - ) - expect(grantReceipt.status).toBe('success') - - const { receipt: renounceReceipt, value: renounceValue } = - await actions.token.renounceRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - }) - - expect(renounceReceipt.status).toBe('success') - expect(renounceValue).toHaveLength(1) - const { role, ...restRenounce } = renounceValue[0]! - expect(restRenounce).toMatchInlineSnapshot(` - { - "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "hasRole": false, - "sender": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - expect(role).toBeDefined() - }) -}) - -describe.todo('setRoleAdmin') - -describe('watchCreate', () => { - test('default', async () => { - const receivedTokens: Array<{ - args: actions.token.watchCreate.Args - log: actions.token.watchCreate.Log - }> = [] - - const unwatch = actions.token.watchCreate(clientWithAccount, { - onTokenCreated: (args, log) => { - receivedTokens.push({ args, log }) - }, - }) - - try { - await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Watch Test Token 1', - symbol: 'WATCH1', - }) - - await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Watch Test Token 2', - symbol: 'WATCH2', - }) - - await setTimeout(500) - - expect(receivedTokens).toHaveLength(2) - } finally { - // Clean up watcher - if (unwatch) unwatch() - } - }) - - test('behavior: filter by tokenId', async () => { - // First, create a token to know what ID we're at - const { tokenId: firstId } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Setup Token', - symbol: 'SETUP', - }, - ) - - // We want to watch for the token with ID = firstId + 2 - const targetTokenId = firstId + 2n - - const receivedTokens: Array<{ - args: actions.token.watchCreate.Args - log: actions.token.watchCreate.Log - }> = [] - - // Start watching for token creation events only for targetTokenId - const unwatch = actions.token.watchCreate(clientWithAccount, { - args: { - tokenId: targetTokenId, - }, - onTokenCreated: (args, log) => { - receivedTokens.push({ args, log }) - }, - }) - - try { - // Create first token (should NOT be captured - ID will be firstId + 1) - await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Filtered Watch Token 1', - symbol: 'FWATCH1', - }) - - // Create second token (should be captured - ID will be firstId + 2 = targetTokenId) - const { tokenId: id2 } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Filtered Watch Token 2', - symbol: 'FWATCH2', - }, - ) - - // Create third token (should NOT be captured - ID will be firstId + 3) - await actions.token.createSync(clientWithAccount, { - currency: 'USD', - name: 'Filtered Watch Token 3', - symbol: 'FWATCH3', - }) - - await setTimeout(500) - - // Should only receive 1 event (for targetTokenId) - expect(receivedTokens).toHaveLength(1) - - expect(receivedTokens.at(0)!.args.tokenId).toBe(targetTokenId) - expect(receivedTokens.at(0)!.args.tokenId).toBe(id2) - - const { token, tokenId, ...rest } = receivedTokens.at(0)!.args - expect(rest).toMatchInlineSnapshot(` - { - "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "currency": "USD", - "name": "Filtered Watch Token 2", - "quoteToken": "0x20C0000000000000000000000000000000000000", - "symbol": "FWATCH2", - } - `) - expect(token).toBeDefined() - expect(tokenId).toBe(targetTokenId) - } finally { - if (unwatch) unwatch() - } - }) -}) - -describe('watchMint', () => { - test('default', async () => { - // Create a new token for testing - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Mint Watch Token', - symbol: 'MINT', - }, - ) - - // Grant issuer role - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - const receivedMints: Array<{ - args: actions.token.watchMint.Args - log: actions.token.watchMint.Log - }> = [] - - // Start watching for mint events - const unwatch = actions.token.watchMint(clientWithAccount, { - token: address, - onMint: (args, log) => { - receivedMints.push({ args, log }) - }, - }) - - try { - // Mint first batch - await actions.token.mintSync(clientWithAccount, { - token: address, - to: account2.address, - amount: parseUnits('100', 6), - }) - - // Mint second batch - await actions.token.mintSync(clientWithAccount, { - token: address, - to: account3.address, - amount: parseUnits('50', 6), - }) - - await setTimeout(500) - - expect(receivedMints).toHaveLength(2) - - expect(receivedMints.at(0)!.args).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - expect(receivedMints.at(1)!.args).toMatchInlineSnapshot(` - { - "amount": 50000000n, - "to": "0x98e503f35D0a019cB0a251aD243a4cCFCF371F46", - } - `) - } finally { - if (unwatch) unwatch() - } - }) - - test('behavior: filter by to address', async () => { - // Create a new token for testing - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Filtered Mint Token', - symbol: 'FMINT', - }, - ) - - // Grant issuer role - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - const receivedMints: Array<{ - args: actions.token.watchMint.Args - log: actions.token.watchMint.Log - }> = [] - - // Start watching for mint events only to account2 - const unwatch = actions.token.watchMint(clientWithAccount, { - token: address, - args: { - to: account2.address, - }, - onMint: (args, log) => { - receivedMints.push({ args, log }) - }, - }) - - try { - // Mint to account2 (should be captured) - await actions.token.mintSync(clientWithAccount, { - token: address, - to: account2.address, - amount: parseUnits('100', 6), - }) - - // Mint to account3 (should NOT be captured) - await actions.token.mintSync(clientWithAccount, { - token: address, - to: account3.address, - amount: parseUnits('50', 6), - }) - - // Mint to account2 again (should be captured) - await actions.token.mintSync(clientWithAccount, { - token: address, - to: account2.address, - amount: parseUnits('75', 6), - }) - - await setTimeout(500) - - // Should only receive 2 events (for account2) - expect(receivedMints).toHaveLength(2) - - expect(receivedMints.at(0)!.args).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - expect(receivedMints.at(1)!.args).toMatchInlineSnapshot(` - { - "amount": 75000000n, - "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - - // Verify all received mints are to account2 - for (const mint of receivedMints) { - expect(mint.args.to).toBe(account2.address) - } - } finally { - if (unwatch) unwatch() - } - }) -}) - -describe('watchApprove', () => { - test('default', async () => { - // Create a new token for testing - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Approval Watch Token', - symbol: 'APPR', - }, - ) - - const receivedApprovals: Array<{ - args: actions.token.watchApprove.Args - log: actions.token.watchApprove.Log - }> = [] - - // Start watching for approval events - const unwatch = actions.token.watchApprove(clientWithAccount, { - token: address, - onApproval: (args, log) => { - receivedApprovals.push({ args, log }) - }, - }) - - try { - // Approve account2 - await actions.token.approveSync(clientWithAccount, { - token: address, - spender: account2.address, - amount: parseUnits('100', 6), - }) - - // Approve account3 - await actions.token.approveSync(clientWithAccount, { - token: address, - spender: account3.address, - amount: parseUnits('50', 6), - }) - - await setTimeout(500) - - expect(receivedApprovals).toHaveLength(2) - - expect(receivedApprovals.at(0)!.args).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - expect(receivedApprovals.at(1)!.args).toMatchInlineSnapshot(` - { - "amount": 50000000n, - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "spender": "0x98e503f35D0a019cB0a251aD243a4cCFCF371F46", - } - `) - } finally { - if (unwatch) unwatch() - } - }) - - test('behavior: filter by spender address', async () => { - // Create a new token for testing - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Filtered Approval Token', - symbol: 'FAPPR', - }, - ) - - const receivedApprovals: Array<{ - args: actions.token.watchApprove.Args - log: actions.token.watchApprove.Log - }> = [] - - // Start watching for approval events only to account2 - const unwatch = actions.token.watchApprove(clientWithAccount, { - token: address, - args: { - spender: account2.address, - }, - onApproval: (args, log) => { - receivedApprovals.push({ args, log }) - }, - }) - - try { - // Approve account2 (should be captured) - await actions.token.approveSync(clientWithAccount, { - token: address, - spender: account2.address, - amount: parseUnits('100', 6), - }) - - // Approve account3 (should NOT be captured) - await actions.token.approveSync(clientWithAccount, { - token: address, - spender: account3.address, - amount: parseUnits('50', 6), - }) - - // Approve account2 again (should be captured) - await actions.token.approveSync(clientWithAccount, { - token: address, - spender: account2.address, - amount: parseUnits('75', 6), - }) - - await setTimeout(500) - - // Should only receive 2 events (for account2) - expect(receivedApprovals).toHaveLength(2) - - expect(receivedApprovals.at(0)!.args).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - expect(receivedApprovals.at(1)!.args).toMatchInlineSnapshot(` - { - "amount": 75000000n, - "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "spender": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - - // Verify all received approvals are for account2 - for (const approval of receivedApprovals) { - expect(approval.args.spender).toBe(account2.address) - } - } finally { - if (unwatch) unwatch() - } - }) -}) - -describe('watchBurn', () => { - test('default', async () => { - // Create a new token for testing - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Burn Watch Token', - symbol: 'BURN', - }, - ) - - // Grant issuer role to mint/burn tokens - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - // Grant issuer role to mint/burn tokens - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: account2.address, - }) - - // Mint tokens to burn later - await actions.token.mintSync(clientWithAccount, { - token: address, - to: clientWithAccount.account.address, - amount: parseUnits('200', 6), - }) - - await actions.token.mintSync(clientWithAccount, { - token: address, - to: account2.address, - amount: parseUnits('100', 6), - }) - - const receivedBurns: Array<{ - args: actions.token.watchBurn.Args - log: actions.token.watchBurn.Log - }> = [] - - // Start watching for burn events - const unwatch = actions.token.watchBurn(clientWithAccount, { - token: address, - onBurn: (args, log) => { - receivedBurns.push({ args, log }) - }, - }) - - try { - // Burn first batch - await actions.token.burnSync(clientWithAccount, { - token: address, - amount: parseUnits('50', 6), - }) - - // Transfer gas to account2 - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - // Burn second batch from account2 - await actions.token.burnSync(clientWithAccount, { - account: account2, - token: address, - amount: parseUnits('25', 6), - }) - - await setTimeout(500) - - expect(receivedBurns).toHaveLength(2) - - expect(receivedBurns.at(0)!.args).toMatchInlineSnapshot(` - { - "amount": 50000000n, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - expect(receivedBurns.at(1)!.args).toMatchInlineSnapshot(` - { - "amount": 25000000n, - "from": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - } finally { - if (unwatch) unwatch() - } - }) - - test('behavior: filter by from address', async () => { - // Create a new token for testing - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Filtered Burn Token', - symbol: 'FBURN', - }, - ) - - // Grant issuer role - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - // Grant issuer role - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: account2.address, - }) - - // Mint tokens to multiple accounts - await actions.token.mintSync(clientWithAccount, { - token: address, - to: clientWithAccount.account.address, - amount: parseUnits('200', 6), - }) - - await actions.token.mintSync(clientWithAccount, { - token: address, - to: account2.address, - amount: parseUnits('200', 6), - }) - - const receivedBurns: Array<{ - args: actions.token.watchBurn.Args - log: actions.token.watchBurn.Log - }> = [] - - // Start watching for burn events only from clientWithAccount.account - const unwatch = actions.token.watchBurn(clientWithAccount, { - token: address, - args: { - from: clientWithAccount.account.address, - }, - onBurn: (args, log) => { - receivedBurns.push({ args, log }) - }, - }) - - try { - // Burn from clientWithAccount.account (should be captured) - await actions.token.burnSync(clientWithAccount, { - token: address, - amount: parseUnits('50', 6), - }) - - // Transfer gas to account2 - await writeContractSync(clientWithAccount, { - abi: Abis.tip20, - address: addresses.alphaUsd, - functionName: 'transfer', - args: [account2.address, parseUnits('1', 6)], - }) - - // Burn from account2 (should NOT be captured) - await actions.token.burnSync(clientWithAccount, { - account: account2, - token: address, - amount: parseUnits('25', 6), - }) - - // Burn from clientWithAccount.account again (should be captured) - await actions.token.burnSync(clientWithAccount, { - token: address, - amount: parseUnits('75', 6), - }) - - await setTimeout(500) - - // Should only receive 2 events (from clientWithAccount.account) - expect(receivedBurns).toHaveLength(2) - - expect(receivedBurns.at(0)!.args).toMatchInlineSnapshot(` - { - "amount": 50000000n, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - expect(receivedBurns.at(1)!.args).toMatchInlineSnapshot(` - { - "amount": 75000000n, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - - // Verify all received burns are from clientWithAccount.account - for (const burn of receivedBurns) { - expect(burn.args.from).toBe(clientWithAccount.account.address) - } - } finally { - if (unwatch) unwatch() - } - }) -}) - -describe('watchAdminRole', () => { - test('default', async () => { - // Create a new token for testing - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Admin Role Watch Token', - symbol: 'ADMIN', - }, - ) - - const receivedAdminUpdates: Array<{ - args: actions.token.watchAdminRole.Args - log: actions.token.watchAdminRole.Log - }> = [] - - // Start watching for role admin updates - const unwatch = actions.token.watchAdminRole(clientWithAccount, { - token: address, - onRoleAdminUpdated: (args, log) => { - receivedAdminUpdates.push({ args, log }) - }, - }) - - try { - // Set role admin for issuer role - const { - receipt: setRoleAdmin1Receipt, - role, - newAdminRole, - ...setRoleAdmin1Result - } = await actions.token.setRoleAdminSync(clientWithAccount, { - token: address, - role: 'issuer', - adminRole: 'pause', - }) - expect(setRoleAdmin1Receipt).toBeDefined() - expect(setRoleAdmin1Result).toMatchInlineSnapshot(` - { - "sender": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - } - `) - expect(role).toBeDefined() - expect(newAdminRole).toBeDefined() - - // Set role admin for pause role - await actions.token.setRoleAdminSync(clientWithAccount, { - token: address, - role: 'pause', - adminRole: 'unpause', - }) - - await setTimeout(500) - - expect(receivedAdminUpdates).toHaveLength(2) - - expect(receivedAdminUpdates.at(0)!.args.sender).toBe( - clientWithAccount.account.address, - ) - expect(receivedAdminUpdates.at(1)!.args.sender).toBe( - clientWithAccount.account.address, - ) - } finally { - if (unwatch) unwatch() - } - }) -}) - -describe('watchRole', () => { - test('default', async () => { - // Create a new token for testing - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Role Watch Token', - symbol: 'ROLE', - }, - ) - - const receivedRoleUpdates: Array<{ - args: actions.token.watchRole.Args - log: actions.token.watchRole.Log - }> = [] - - // Start watching for role membership updates - const unwatch = actions.token.watchRole(clientWithAccount, { - token: address, - onRoleUpdated: (args, log) => { - receivedRoleUpdates.push({ args, log }) - }, - }) - - try { - // Grant issuer role to account2 - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: account2.address, - }) - - // Grant pause role to account3 - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['pause'], - to: account3.address, - }) - - // Revoke issuer role from account2 - await actions.token.revokeRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - from: account2.address, - }) - - await setTimeout(500) - - expect(receivedRoleUpdates).toHaveLength(3) - - // First event: grant issuer - expect(receivedRoleUpdates.at(0)!.args.type).toBe('granted') - expect(receivedRoleUpdates.at(0)!.args.account).toBe(account2.address) - expect(receivedRoleUpdates.at(0)!.args.hasRole).toBe(true) - - // Second event: grant pause - expect(receivedRoleUpdates.at(1)!.args.type).toBe('granted') - expect(receivedRoleUpdates.at(1)!.args.account).toBe(account3.address) - expect(receivedRoleUpdates.at(1)!.args.hasRole).toBe(true) - - // Third event: revoke issuer - expect(receivedRoleUpdates.at(2)!.args.type).toBe('revoked') - expect(receivedRoleUpdates.at(2)!.args.account).toBe(account2.address) - expect(receivedRoleUpdates.at(2)!.args.hasRole).toBe(false) - } finally { - if (unwatch) unwatch() - } - }) - - test('behavior: filter by account address', async () => { - // Create a new token for testing - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Filtered Role Token', - symbol: 'FROLE', - }, - ) - - const receivedRoleUpdates: Array<{ - args: actions.token.watchRole.Args - log: actions.token.watchRole.Log - }> = [] - - // Start watching for role updates only for account2 - const unwatch = actions.token.watchRole(clientWithAccount, { - token: address, - args: { - account: account2.address, - }, - onRoleUpdated: (args, log) => { - receivedRoleUpdates.push({ args, log }) - }, - }) - - try { - // Grant issuer role to account2 (should be captured) - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: account2.address, - }) - - // Grant pause role to account3 (should NOT be captured) - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['pause'], - to: account3.address, - }) - - // Revoke issuer role from account2 (should be captured) - await actions.token.revokeRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - from: account2.address, - }) - - await setTimeout(500) - - // Should only receive 2 events (for account2) - expect(receivedRoleUpdates).toHaveLength(2) - - // First: grant to account2 - expect(receivedRoleUpdates.at(0)!.args.type).toBe('granted') - expect(receivedRoleUpdates.at(0)!.args.account).toBe(account2.address) - expect(receivedRoleUpdates.at(0)!.args.hasRole).toBe(true) - - // Second: revoke from account2 - expect(receivedRoleUpdates.at(1)!.args.type).toBe('revoked') - expect(receivedRoleUpdates.at(1)!.args.account).toBe(account2.address) - expect(receivedRoleUpdates.at(1)!.args.hasRole).toBe(false) - - // Verify all received events are for account2 - for (const update of receivedRoleUpdates) { - expect(update.args.account).toBe(account2.address) - } - } finally { - if (unwatch) unwatch() - } - }) -}) - -describe('watchTransfer', () => { - beforeAll(async () => { - await fetch(`${rpcUrl}/restart`) - }) - - test('default', async () => { - // Create a new token for testing - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Transfer Watch Token', - symbol: 'XFER', - }, - ) - - // Grant issuer role to mint tokens - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - // Mint tokens to transfer - await actions.token.mintSync(clientWithAccount, { - token: address, - to: clientWithAccount.account.address, - amount: parseUnits('500', 6), - }) - - const receivedTransfers: Array<{ - args: actions.token.watchTransfer.Args - log: actions.token.watchTransfer.Log - }> = [] - - // Start watching for transfer events - const unwatch = actions.token.watchTransfer(clientWithAccount, { - token: address, - onTransfer: (args, log) => { - receivedTransfers.push({ args, log }) - }, - }) - - try { - // Transfer to account2 - await actions.token.transferSync(clientWithAccount, { - token: address, - to: account2.address, - amount: parseUnits('100', 6), - }) - - // Transfer to account3 - await actions.token.transferSync(clientWithAccount, { - token: address, - to: account3.address, - amount: parseUnits('50', 6), - }) - - await setTimeout(200) - - expect(receivedTransfers.length).toBeGreaterThanOrEqual(2) - - expect(receivedTransfers.at(0)!.args).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - expect(receivedTransfers.at(1)!.args).toMatchInlineSnapshot(` - { - "amount": 50000000n, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "to": "0x98e503f35D0a019cB0a251aD243a4cCFCF371F46", - } - `) - } finally { - if (unwatch) unwatch() - } - }) - - test('behavior: filter by to address', async () => { - // Create a new token for testing - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Filtered Transfer Token', - symbol: 'FXFER', - }, - ) - - // Grant issuer role - await actions.token.grantRolesSync(clientWithAccount, { - token: address, - roles: ['issuer'], - to: clientWithAccount.account.address, - }) - - // Mint tokens - await actions.token.mintSync(clientWithAccount, { - token: address, - to: clientWithAccount.account.address, - amount: parseUnits('500', 6), - }) - - const receivedTransfers: Array<{ - args: actions.token.watchTransfer.Args - log: actions.token.watchTransfer.Log - }> = [] - - // Start watching for transfer events only to account2 - const unwatch = actions.token.watchTransfer(clientWithAccount, { - token: address, - args: { - to: account2.address, - }, - onTransfer: (args, log) => { - receivedTransfers.push({ args, log }) - }, - }) - - try { - // Transfer to account2 (should be captured) - await actions.token.transferSync(clientWithAccount, { - token: address, - to: account2.address, - amount: parseUnits('100', 6), - }) - - // Transfer to account3 (should NOT be captured) - await actions.token.transferSync(clientWithAccount, { - token: address, - to: account3.address, - amount: parseUnits('50', 6), - }) - - // Transfer to account2 again (should be captured) - await actions.token.transferSync(clientWithAccount, { - token: address, - to: account2.address, - amount: parseUnits('75', 6), - }) - - await setTimeout(500) - - // Should only receive 2 events (to account2) - expect(receivedTransfers).toHaveLength(2) - - expect(receivedTransfers.at(0)!.args).toMatchInlineSnapshot(` - { - "amount": 100000000n, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - expect(receivedTransfers.at(1)!.args).toMatchInlineSnapshot(` - { - "amount": 75000000n, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "to": "0x8C8d35429F74ec245F8Ef2f4Fd1e551cFF97d650", - } - `) - - // Verify all received transfers are to account2 - for (const transfer of receivedTransfers) { - expect(transfer.args.to).toBe(account2.address) - } - } finally { - if (unwatch) unwatch() - } - }) -}) - -describe('watchUpdateQuoteToken', () => { - test('default', async () => { - // Create quote token - const { token: quoteTokenAddress } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Watch Quote Token', - symbol: 'WLINK', - }, - ) - - // Create main token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Watch Main Token', - symbol: 'WMAIN', - }, - ) - - const receivedUpdates: Array<{ - args: actions.token.watchUpdateQuoteToken.Args - log: actions.token.watchUpdateQuoteToken.Log - }> = [] - - // Start watching for quote token update events - const unwatch = actions.token.watchUpdateQuoteToken(clientWithAccount, { - token: address, - onUpdateQuoteToken: (args, log) => { - receivedUpdates.push({ args, log }) - }, - }) - - try { - // Step 1: Prepare update quote token (should emit NextQuoteTokenSet) - await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, { - token: address, - quoteToken: quoteTokenAddress, - }) - - // Step 2: Finalize the update (should emit QuoteTokenUpdateFinalized) - await actions.token.updateQuoteTokenSync(clientWithAccount, { - token: address, - }) - - await setTimeout(500) - - // Should receive 2 events: one for update, one for finalized - expect(receivedUpdates).toHaveLength(2) - - // First event: update proposed (not finalized) - expect(receivedUpdates.at(0)!.args.completed).toBe(false) - expect(receivedUpdates.at(0)!.args.nextQuoteToken).toBe(quoteTokenAddress) - expect(receivedUpdates.at(0)!.args.updater).toBe( - clientWithAccount.account.address, - ) - - // Second event: update finalized - expect(receivedUpdates.at(1)!.args.completed).toBe(true) - expect(receivedUpdates.at(1)!.args.newQuoteToken).toBe(quoteTokenAddress) - expect(receivedUpdates.at(1)!.args.updater).toBe( - clientWithAccount.account.address, - ) - } finally { - if (unwatch) unwatch() - } - }) - - test('behavior: only proposed updates', async () => { - // Create quote token - const { token: quoteTokenAddress } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Proposed Quote Token', - symbol: 'PLINK', - }, - ) - - // Create main token - const { token: address } = await actions.token.createSync( - clientWithAccount, - { - currency: 'USD', - name: 'Proposed Main Token', - symbol: 'PMAIN', - }, - ) - - const receivedUpdates: Array<{ - args: actions.token.watchUpdateQuoteToken.Args - log: actions.token.watchUpdateQuoteToken.Log - }> = [] - - // Start watching - const unwatch = actions.token.watchUpdateQuoteToken(clientWithAccount, { - token: address, - onUpdateQuoteToken: (args, log) => { - receivedUpdates.push({ args, log }) - }, - }) - - try { - // Only update (don't finalize) - await actions.token.prepareUpdateQuoteTokenSync(clientWithAccount, { - token: address, - quoteToken: quoteTokenAddress, - }) - - await setTimeout(500) - - // Should only receive 1 event (not finalized) - expect(receivedUpdates).toHaveLength(1) - expect(receivedUpdates.at(0)!.args.completed).toBe(false) - expect(receivedUpdates.at(0)!.args.nextQuoteToken).toBe(quoteTokenAddress) - } finally { - if (unwatch) unwatch() - } - }) -}) diff --git a/src/viem/Actions/token.ts b/src/viem/Actions/token.ts deleted file mode 100644 index edde4605..00000000 --- a/src/viem/Actions/token.ts +++ /dev/null @@ -1,4458 +0,0 @@ -import * as Hex from 'ox/Hex' -import { TokenId, TokenRole } from 'ox/tempo' -import { - type Account, - type Address, - type BaseErrorType, - type Chain, - type Client, - type ExtractAbiItem, - encodeFunctionData, - type GetEventArgs, - type Log, - parseEventLogs, - type ReadContractReturnType, - type SendTransactionSyncParameters, - type TransactionReceipt, - type Transport, - type Log as viem_Log, - type WatchContractEventParameters, - type WatchContractEventReturnType, - type WriteContractReturnType, -} from 'viem' -import { parseAccount } from 'viem/accounts' -import { - multicall, - readContract, - sendTransaction, - sendTransactionSync, - watchContractEvent, - writeContract, - writeContractSync, -} from 'viem/actions' -import type { Compute, OneOf, UnionOmit } from '../../internal/types.js' -import * as Abis from '../Abis.js' -import * as Addresses from '../Addresses.js' -import type { - GetAccountParameter, - ReadParameters, - WriteParameters, -} from '../internal/types.js' -import { defineCall } from '../internal/utils.js' - -/** - * Approves a spender to transfer TIP20 tokens on behalf of the caller. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.approve(client, { - * spender: '0x...', - * amount: 100n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function approve< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: approve.Parameters, -): Promise { - const { token, ...rest } = parameters - return approve.inner(writeContract, client, parameters, { ...rest, token }) -} - -export namespace approve { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount of tokens to approve. */ - amount: bigint - /** Address of the spender. */ - spender: Address - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: approve.Parameters, - args: Args, - ): Promise> { - const call = approve.call(args) - return (await action(client, { - ...parameters, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `approve` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.approve.call({ - * spender: '0x20c0...beef', - * amount: 100n, - * token: '0x20c0...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { spender, amount, token } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'approve', - args: [spender, amount], - }) - } - - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'Approval', - }) - if (!log) throw new Error('`Approval` event not found.') - return log - } -} - -/** - * Approves a spender to transfer TIP20 tokens on behalf of the caller. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.approveSync(client, { - * spender: '0x...', - * amount: 100n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function approveSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: approveSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await approve.inner( - writeContractSync, - client, - { ...parameters, throwOnReceiptRevert } as never, - rest, - ) - const { args } = approve.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace approveSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = approve.Parameters - - export type Args = approve.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip20, - 'Approval', - { - IndexedOnly: false - Required: true - } - > & { - /** Transaction receipt. */ - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Burns TIP20 tokens from a blocked address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.burnBlocked(client, { - * from: '0x...', - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function burnBlocked< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: burnBlocked.Parameters, -): Promise { - return burnBlocked.inner(writeContract, client, parameters) -} - -export namespace burnBlocked { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount of tokens to burn. */ - amount: bigint - /** Address to burn tokens from. */ - from: Address - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: burnBlocked.Parameters, - ): Promise> { - const { amount, from, token, ...rest } = parameters - const call = burnBlocked.call({ amount, from, token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `burnBlocked` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.burnBlocked.call({ - * from: '0x20c0...beef', - * amount: 100n, - * token: '0x20c0...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { from, amount, token } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'burnBlocked', - args: [from, amount], - }) - } - - /** - * Extracts the event from the logs. - * - * @param logs - Logs. - * @returns The event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'BurnBlocked', - }) - if (!log) throw new Error('`BurnBlocked` event not found.') - return log - } -} - -/** - * Burns TIP20 tokens from a blocked address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.burnBlockedSync(client, { - * from: '0x...', - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function burnBlockedSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: burnBlockedSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await burnBlocked.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = burnBlocked.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace burnBlockedSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = burnBlocked.Parameters - - export type Args = burnBlocked.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip20, - 'BurnBlocked', - { - IndexedOnly: false - Required: true - } - > & { - /** Transaction receipt. */ - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Burns TIP20 tokens from the caller's balance. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.burn(client, { - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function burn< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: burn.Parameters, -): Promise { - return burn.inner(writeContract, client, parameters) -} - -export namespace burn { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount of tokens to burn. */ - amount: bigint - /** Memo to include in the transfer. */ - memo?: Hex.Hex | undefined - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: burn.Parameters, - ): Promise> { - const { amount, memo, token, ...rest } = parameters - const call = burn.call({ amount, memo, token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `burn` or `burnWithMemo` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.burn.call({ - * amount: 100n, - * token: '0x20c0...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { amount, memo, token } = args - const callArgs = memo - ? ({ - functionName: 'burnWithMemo', - args: [amount, Hex.padLeft(memo, 32)], - } as const) - : ({ - functionName: 'burn', - args: [amount], - } as const) - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - ...callArgs, - }) - } - - /** - * Extracts the event from the logs. - * - * @param logs - Logs. - * @returns The event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'Burn', - }) - if (!log) throw new Error('`Burn` event not found.') - return log - } -} - -/** - * Burns TIP20 tokens from the caller's balance. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.burnSync(client, { - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function burnSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: burnSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await burn.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = burn.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace burnSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = burn.Parameters - - export type Args = burn.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip20, - 'Burn', - { - IndexedOnly: false - Required: true - } - > & { - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Changes the transfer policy ID for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.changeTransferPolicy(client, { - * token: '0x...', - * policyId: 1n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function changeTransferPolicy< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: changeTransferPolicy.Parameters, -): Promise { - return changeTransferPolicy.inner(writeContract, client, parameters) -} - -export namespace changeTransferPolicy { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** New transfer policy ID. */ - policyId: bigint - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: changeTransferPolicy.Parameters, - ): Promise> { - const { policyId, token, ...rest } = parameters - const call = changeTransferPolicy.call({ policyId, token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `changeTransferPolicyId` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.changeTransferPolicy.call({ - * token: '0x20c0...babe', - * policyId: 1n, - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token, policyId } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'changeTransferPolicyId', - args: [policyId], - }) - } - - /** - * Extracts the event from the logs. - * - * @param logs - Logs. - * @returns The event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'TransferPolicyUpdate', - }) - if (!log) throw new Error('`TransferPolicyUpdate` event not found.') - return log - } -} - -/** - * Changes the transfer policy ID for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.changeTransferPolicySync(client, { - * token: '0x...', - * policyId: 1n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function changeTransferPolicySync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: changeTransferPolicySync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await changeTransferPolicy.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = changeTransferPolicy.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace changeTransferPolicySync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = changeTransferPolicy.Parameters - - export type Args = changeTransferPolicy.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip20, - 'TransferPolicyUpdate', - { - IndexedOnly: false - Required: true - } - > & { - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Creates a new TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.create(client, { - * name: 'My Token', - * symbol: 'MTK', - * currency: 'USD', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function create< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: create.Parameters, -): Promise { - return create.inner(writeContract, client, parameters) -} - -export namespace create { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & - Omit & - (account extends Account - ? { admin?: Account | Address | undefined } - : { admin: Account | Address }) - - export type Args = { - /** Admin address. */ - admin: Address - /** Currency (e.g. "USD"). */ - currency: string - /** Token name. */ - name: string - /** quote token. */ - quoteToken?: TokenId.TokenIdOrAddress | undefined - /** Token symbol. */ - symbol: string - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: any, - ): Promise> { - const { - account = client.account, - admin: admin_ = client.account, - chain = client.chain, - ...rest - } = parameters - const admin = admin_ ? parseAccount(admin_) : undefined - if (!admin) throw new Error('admin is required.') - - const call = create.call({ ...rest, admin: admin.address }) - - return (await action( - client as never, - { - ...parameters, - account, - chain, - ...call, - } as never, - )) as never - } - - /** - * Defines a call to the `createToken` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.create.call({ - * name: 'My Token', - * symbol: 'MTK', - * currency: 'USD', - * admin: '0xfeed...fede', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { - name, - symbol, - currency, - quoteToken = Addresses.pathUsd, - admin, - } = args - return defineCall({ - address: Addresses.tip20Factory, - abi: Abis.tip20Factory, - args: [name, symbol, currency, TokenId.toAddress(quoteToken), admin], - functionName: 'createToken', - }) - } - - /** - * Extracts the `TokenCreated` event from logs. - * - * @param logs - The logs. - * @returns The `TokenCreated` event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20Factory, - logs, - eventName: 'TokenCreated', - strict: true, - }) - if (!log) throw new Error('`TokenCreated` event not found.') - return log - } -} - -/** - * Creates a new TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.createSync(client, { - * name: 'My Token', - * symbol: 'MTK', - * currency: 'USD', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function createSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: createSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await create.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - - const { args } = create.extractEvent(receipt.logs) - - return { - ...args, - receipt, - } as never -} - -export namespace createSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = create.Parameters - - export type Args = create.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip20Factory, - 'TokenCreated', - { IndexedOnly: false; Required: true } - > & { - /** Transaction receipt. */ - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Gets TIP20 token allowance. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const allowance = await Actions.token.getAllowance(client, { - * spender: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The token allowance. - */ -export async function getAllowance< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: getAllowance.Parameters, -): Promise { - const { account = client.account } = parameters - const address = account ? parseAccount(account).address : undefined - if (!address) throw new Error('account is required.') - return readContract(client, { - ...parameters, - ...getAllowance.call({ ...parameters, account: address }), - }) -} - -export namespace getAllowance { - export type Parameters< - account extends Account | undefined = Account | undefined, - > = ReadParameters & GetAccountParameter & Omit & {} - - export type Args = { - /** Account address. */ - account: Address - /** Address of the spender. */ - spender: Address - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.tip20, - 'allowance', - never - > - - /** - * Defines a call to the `allowance` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { account, spender, token } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'allowance', - args: [account, spender], - }) - } -} - -/** - * Gets TIP20 token balance for an address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const balance = await Actions.token.getBalance(client, { - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The token balance. - */ -export async function getBalance< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: getBalance.Parameters, -): Promise { - const { account = client.account, ...rest } = parameters - const address = account ? parseAccount(account).address : undefined - if (!address) throw new Error('account is required.') - return readContract(client, { - ...rest, - ...getBalance.call({ account: address, ...rest }), - }) -} - -export namespace getBalance { - export type Parameters< - account extends Account | undefined = Account | undefined, - > = ReadParameters & GetAccountParameter & Omit - - export type Args = { - /** Account address. */ - account: Address - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.tip20, - 'balanceOf', - never - > - - /** - * Defines a call to the `balanceOf` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { account, token } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'balanceOf', - args: [account], - }) - } -} - -/** - * Gets TIP20 token metadata including name, symbol, currency, decimals, and total supply. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const metadata = await Actions.token.getMetadata(client, { - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The token metadata. - */ -export async function getMetadata( - client: Client, - parameters: getMetadata.Parameters, -): Promise { - const { token, ...rest } = parameters - const address = TokenId.toAddress(token) - const abi = Abis.tip20 - - if (TokenId.from(token) === TokenId.fromAddress(Addresses.pathUsd)) - return multicall(client, { - ...rest, - contracts: [ - { - address, - abi, - functionName: 'currency', - }, - { - address, - abi, - functionName: 'decimals', - }, - { - address, - abi, - functionName: 'name', - }, - { - address, - abi, - functionName: 'symbol', - }, - { - address, - abi, - functionName: 'totalSupply', - }, - ] as const, - allowFailure: false, - deployless: true, - }).then(([currency, decimals, name, symbol, totalSupply]) => ({ - name, - symbol, - currency, - decimals, - totalSupply, - })) - - return multicall(client, { - ...rest, - contracts: [ - { - address, - abi, - functionName: 'currency', - }, - { - address, - abi, - functionName: 'decimals', - }, - { - address, - abi, - functionName: 'quoteToken', - }, - { - address, - abi, - functionName: 'name', - }, - { - address, - abi, - functionName: 'paused', - }, - { - address, - abi, - functionName: 'supplyCap', - }, - { - address, - abi, - functionName: 'symbol', - }, - { - address, - abi, - functionName: 'totalSupply', - }, - { - address, - abi, - functionName: 'transferPolicyId', - }, - ] as const, - allowFailure: false, - deployless: true, - }).then( - ([ - currency, - decimals, - quoteToken, - name, - paused, - supplyCap, - symbol, - totalSupply, - transferPolicyId, - ]) => ({ - name, - symbol, - currency, - decimals, - quoteToken, - totalSupply, - paused, - supplyCap, - transferPolicyId, - }), - ) -} - -export declare namespace getMetadata { - export type Parameters = { - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = Compute<{ - /** - * Currency (e.g. "USD"). - */ - currency: string - /** - * Decimals of the token. - */ - decimals: number - /** - * Quote token. - * - * Returns `undefined` for the default quote token (`0x20c...0000`). - */ - quoteToken?: Address | undefined - /** - * Name of the token. - */ - name: string - /** - * Whether the token is paused. - * - * Returns `undefined` for the default quote token (`0x20c...0000`). - */ - paused?: boolean | undefined - /** - * Supply cap. - * - * Returns `undefined` for the default quote token (`0x20c...0000`). - */ - supplyCap?: bigint | undefined - /** - * Symbol of the token. - */ - symbol: string - /** - * Total supply of the token. - */ - totalSupply: bigint - /** - * Transfer policy ID. - * 0="always-reject", 1="always-allow", >2=custom policy - * - * Returns `undefined` for the default quote token (`0x20c...0000`). - */ - transferPolicyId?: bigint | undefined - }> -} - -/** - * Gets the admin role for a specific role in a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const adminRole = await Actions.token.getRoleAdmin(client, { - * role: 'issuer', - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The admin role hash. - */ -export async function getRoleAdmin( - client: Client, - parameters: getRoleAdmin.Parameters, -): Promise { - return readContract(client, { - ...parameters, - ...getRoleAdmin.call(parameters), - }) -} - -export namespace getRoleAdmin { - export type Parameters = ReadParameters & Args - - export type Args = { - /** Role to get admin for. */ - role: TokenRole.TokenRole - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.tip20, - 'getRoleAdmin', - never - > - - /** - * Defines a call to the `getRoleAdmin` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { role, token } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'getRoleAdmin', - args: [TokenRole.serialize(role)], - }) - } -} - -/** - * Checks if an account has a specific role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const hasRole = await Actions.token.hasRole(client, { - * account: '0x...', - * role: 'issuer', - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns Whether the account has the role. - */ -export async function hasRole< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: hasRole.Parameters, -): Promise { - const { account = client.account } = parameters - const address = account ? parseAccount(account).address : undefined - if (!address) throw new Error('account is required.') - return readContract(client, { - ...parameters, - ...hasRole.call({ ...parameters, account: address }), - }) -} - -export namespace hasRole { - export type Parameters< - account extends Account | undefined = Account | undefined, - > = ReadParameters & Omit & GetAccountParameter - - export type Args = { - /** Account address to check. */ - account: Address - /** Role to check. */ - role: TokenRole.TokenRole - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = ReadContractReturnType< - typeof Abis.tip20, - 'hasRole', - never - > - - /** - * Defines a call to the `hasRole` function. - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { account, role, token } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'hasRole', - args: [account, TokenRole.serialize(role)], - }) - } -} - -/** - * Grants a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.grantRoles(client, { - * token: '0x...', - * to: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function grantRoles< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: grantRoles.Parameters, -): Promise { - return grantRoles.inner(sendTransaction, client, parameters) -} - -export namespace grantRoles { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & - Omit & { - /** Role to grant. */ - roles: readonly TokenRole.TokenRole[] - } - - export type Args = { - /** Role to grant. */ - role: TokenRole.TokenRole - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - /** Address to grant the role to. */ - to: Address - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof sendTransaction | typeof sendTransactionSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: grantRoles.Parameters, - ): Promise> { - return (await action(client, { - ...parameters, - calls: parameters.roles.map((role) => { - const call = grantRoles.call({ ...parameters, role }) - return { - ...call, - data: encodeFunctionData(call), - } - }), - } as never)) as never - } - - /** - * Defines a call to the `grantRole` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.grantRoles.call({ - * token: '0x20c0...babe', - * to: '0x20c0...beef', - * role: 'issuer', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token, to, role } = args - const roleHash = TokenRole.serialize(role) - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'grantRole', - args: [roleHash, to], - }) - } - - /** - * Extracts the events from the logs. - * - * @param logs - Logs. - * @returns The events. - */ - export function extractEvents(logs: Log[]) { - const events = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'RoleMembershipUpdated', - }) - if (events.length === 0) - throw new Error('`RoleMembershipUpdated` events not found.') - return events - } -} - -/** - * Grants a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.grantRolesSync(client, { - * token: '0x...', - * to: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function grantRolesSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: grantRolesSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await grantRoles.inner(sendTransactionSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const events = grantRoles.extractEvents(receipt.logs) - const value = events.map((event) => event.args) - return { - receipt, - value, - } -} - -export namespace grantRolesSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = grantRoles.Parameters - - export type Args = grantRoles.Args - - export type ReturnValue = { - receipt: TransactionReceipt - value: readonly GetEventArgs< - typeof Abis.tip20, - 'RoleMembershipUpdated', - { IndexedOnly: false; Required: true } - >[] - } - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Mints TIP20 tokens to an address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.mint(client, { - * to: '0x...', - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function mint< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: mint.Parameters, -): Promise { - return mint.inner(writeContract, client, parameters) -} - -export namespace mint { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount of tokens to mint. */ - amount: bigint - /** Memo to include in the mint. */ - memo?: Hex.Hex | undefined - /** Address to mint tokens to. */ - to: Address - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: any, - ): Promise> { - const call = mint.call(parameters) - return (await action(client, { - ...parameters, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `mint` or `mintWithMemo` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.mint.call({ - * to: '0x20c0...beef', - * amount: 100n, - * token: '0x20c0...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { to, amount, memo, token } = args - const callArgs = memo - ? ({ - functionName: 'mintWithMemo', - args: [to, amount, Hex.padLeft(memo, 32)], - } as const) - : ({ - functionName: 'mint', - args: [to, amount], - } as const) - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - ...callArgs, - }) - } - - /** - * Extracts the event from the logs. - * - * @param logs - Logs. - * @returns The event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'Mint', - }) - if (!log) throw new Error('`Mint` event not found.') - return log - } -} - -/** - * Mints TIP20 tokens to an address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.mintSync(client, { - * to: '0x...', - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function mintSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: mintSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await mint.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = mint.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace mintSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = mint.Parameters - - export type Args = mint.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip20, - 'Mint', - { - IndexedOnly: false - Required: true - } - > & { - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Pauses a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.pause(client, { - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function pause< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: pause.Parameters, -): Promise { - return pause.inner(writeContract, client, parameters) -} - -export namespace pause { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: pause.Parameters, - ): Promise> { - const { token, ...rest } = parameters - const call = pause.call({ token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `pause` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.pause.call({ - * token: '0x20c0...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'pause', - args: [], - }) - } - - /** - * Extracts the event from the logs. - * - * @param logs - Logs. - * @returns The event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'PauseStateUpdate', - }) - if (!log) throw new Error('`PauseStateUpdate` event not found.') - return log - } -} - -/** - * Pauses a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.pauseSync(client, { - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function pauseSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: pauseSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await pause.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = pause.extractEvent(receipt.logs) - return { - ...args, - receipt, - } -} - -export namespace pauseSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = pause.Parameters - - export type Args = pause.Args - - export type ReturnValue = GetEventArgs< - typeof Abis.tip20, - 'PauseStateUpdate', - { IndexedOnly: false; Required: true } - > & { - receipt: TransactionReceipt - } - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Renounces a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.renounceRoles(client, { - * token: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function renounceRoles< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: renounceRoles.Parameters, -): Promise { - return renounceRoles.inner(sendTransaction, client, parameters) -} - -export namespace renounceRoles { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & - Omit & { - /** Roles to renounce. */ - roles: readonly TokenRole.TokenRole[] - } - - export type Args = { - /** Role to renounce. */ - role: TokenRole.TokenRole - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof sendTransaction | typeof sendTransactionSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: renounceRoles.Parameters, - ): Promise> { - return (await action(client, { - ...parameters, - calls: parameters.roles.map((role) => { - const call = renounceRoles.call({ ...parameters, role }) - return { - ...call, - data: encodeFunctionData(call), - } - }), - } as never)) as never - } - - /** - * Defines a call to the `renounceRole` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.renounceRoles.call({ - * token: '0x20c0...babe', - * role: 'issuer', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token, role } = args - const roleHash = TokenRole.serialize(role) - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'renounceRole', - args: [roleHash], - }) - } - - /** - * Extracts the events from the logs. - * - * @param logs - Logs. - * @returns The events. - */ - export function extractEvents(logs: Log[]) { - const events = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'RoleMembershipUpdated', - }) - if (events.length === 0) - throw new Error('`RoleMembershipUpdated` events not found.') - return events - } -} - -/** - * Renounces a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.renounceRolesSync(client, { - * token: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function renounceRolesSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: renounceRolesSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await renounceRoles.inner(sendTransactionSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const events = renounceRoles.extractEvents(receipt.logs) - const value = events.map((event) => event.args) - return { - receipt, - value, - } -} - -export namespace renounceRolesSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = renounceRoles.Parameters - - export type Args = renounceRoles.Args - - export type ReturnValue = { - receipt: TransactionReceipt - value: readonly GetEventArgs< - typeof Abis.tip20, - 'RoleMembershipUpdated', - { IndexedOnly: false; Required: true } - >[] - } - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Revokes a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.revokeRoles(client, { - * token: '0x...', - * from: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function revokeRoles< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: revokeRoles.Parameters, -): Promise { - return revokeRoles.inner(sendTransaction, client, parameters) -} - -export namespace revokeRoles { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = SendTransactionSyncParameters & - Omit & { - /** Role to revoke. */ - roles: readonly TokenRole.TokenRole[] - } - - export type Args = { - /** Address to revoke the role from. */ - from: Address - /** Role to revoke. */ - role: TokenRole.TokenRole - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof sendTransaction | typeof sendTransactionSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: revokeRoles.Parameters, - ): Promise> { - return (await action(client, { - ...parameters, - calls: parameters.roles.map((role) => { - const call = revokeRoles.call({ ...parameters, role }) - return { - ...call, - data: encodeFunctionData(call), - } - }), - } as never)) as never - } - - /** - * Defines a call to the `revokeRole` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.revokeRoles.call({ - * token: '0x20c0...babe', - * from: '0x20c0...beef', - * role: 'issuer', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token, from, role } = args - const roleHash = TokenRole.serialize(role) - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'revokeRole', - args: [roleHash, from], - }) - } - - /** - * Extracts the events from the logs. - * - * @param logs - Logs. - * @returns The events. - */ - export function extractEvents(logs: Log[]) { - const events = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'RoleMembershipUpdated', - }) - if (events.length === 0) - throw new Error('`RoleMembershipUpdated` events not found.') - return events - } -} - -/** - * Revokes a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.revokeRolesSync(client, { - * token: '0x...', - * from: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function revokeRolesSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: revokeRolesSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await revokeRoles.inner(sendTransactionSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const events = revokeRoles.extractEvents(receipt.logs) - const value = events.map((event) => event.args) - return { - receipt, - value, - } -} - -export namespace revokeRolesSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = revokeRoles.Parameters - - export type Args = revokeRoles.Args - - export type ReturnValue = { - receipt: TransactionReceipt - value: readonly GetEventArgs< - typeof Abis.tip20, - 'RoleMembershipUpdated', - { IndexedOnly: false; Required: true } - >[] - } - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Sets the supply cap for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.setSupplyCap(client, { - * token: '0x...', - * supplyCap: 1000000n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function setSupplyCap< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: setSupplyCap.Parameters, -): Promise { - return setSupplyCap.inner(writeContract, client, parameters) -} - -export namespace setSupplyCap { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** New supply cap. */ - supplyCap: bigint - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: setSupplyCap.Parameters, - ): Promise> { - const { supplyCap, token, ...rest } = parameters - const call = setSupplyCap.call({ supplyCap, token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `setSupplyCap` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.setSupplyCap.call({ - * token: '0x20c0...babe', - * supplyCap: 1000000n, - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token, supplyCap } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'setSupplyCap', - args: [supplyCap], - }) - } - - /** - * Extracts the event from the logs. - * - * @param logs - Logs. - * @returns The event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'SupplyCapUpdate', - }) - if (!log) throw new Error('`SupplyCapUpdate` event not found.') - return log - } -} - -/** - * Sets the supply cap for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.setSupplyCapSync(client, { - * token: '0x...', - * supplyCap: 1000000n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function setSupplyCapSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: setSupplyCapSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await setSupplyCap.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = setSupplyCap.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace setSupplyCapSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = setSupplyCap.Parameters - - export type Args = setSupplyCap.Args - - export type ReturnValue = GetEventArgs< - typeof Abis.tip20, - 'SupplyCapUpdate', - { IndexedOnly: false; Required: true } - > & { - receipt: TransactionReceipt - } - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Sets the admin role for a specific role in a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.setRoleAdmin(client, { - * token: '0x...', - * role: 'issuer', - * adminRole: 'admin', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function setRoleAdmin< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: setRoleAdmin.Parameters, -): Promise { - return setRoleAdmin.inner(writeContract, client, parameters) -} - -export namespace setRoleAdmin { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** New admin role. */ - adminRole: TokenRole.TokenRole - /** Role to set admin for. */ - role: TokenRole.TokenRole - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: setRoleAdmin.Parameters, - ): Promise> { - const { adminRole, role, token, ...rest } = parameters - const call = setRoleAdmin.call({ adminRole, role, token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `setRoleAdmin` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.setRoleAdmin.call({ - * token: '0x20c0...babe', - * role: 'issuer', - * adminRole: 'admin', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token, role, adminRole } = args - const roleHash = TokenRole.serialize(role) - const adminRoleHash = TokenRole.serialize(adminRole) - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'setRoleAdmin', - args: [roleHash, adminRoleHash], - }) - } - - /** - * Extracts the event from the logs. - * - * @param logs - Logs. - * @returns The event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'RoleAdminUpdated', - }) - if (!log) throw new Error('`RoleAdminUpdated` event not found.') - return log - } -} - -/** - * Sets the admin role for a specific role in a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.setRoleAdminSync(client, { - * token: '0x...', - * role: 'issuer', - * adminRole: 'admin', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function setRoleAdminSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: setRoleAdminSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await setRoleAdmin.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = setRoleAdmin.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace setRoleAdminSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = setRoleAdmin.Parameters - - export type Args = setRoleAdmin.Args - - export type ReturnValue = GetEventArgs< - typeof Abis.tip20, - 'RoleAdminUpdated', - { IndexedOnly: false; Required: true } - > & { - receipt: TransactionReceipt - } - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Transfers TIP20 tokens to another address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.transfer(client, { - * to: '0x...', - * amount: 100n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function transfer< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: transfer.Parameters, -): Promise { - return transfer.inner(writeContract, client, parameters) -} - -export namespace transfer { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Amount of tokens to transfer. */ - amount: bigint - /** Address to transfer tokens from. */ - from?: Address | undefined - /** Memo to include in the transfer. */ - memo?: Hex.Hex | undefined - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - /** Address to transfer tokens to. */ - to: Address - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: transfer.Parameters, - ): Promise> { - const { amount, from, memo, token, to, ...rest } = parameters - const call = transfer.call({ amount, from, memo, token, to }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `transfer`, `transferFrom`, `transferWithMemo`, or `transferFromWithMemo` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.transfer.call({ - * to: '0x20c0...beef', - * amount: 100n, - * token: '0x20c0...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { amount, from, memo, token, to } = args - const callArgs = (() => { - if (memo && from) - return { - functionName: 'transferFromWithMemo', - args: [from, to, amount, Hex.padLeft(memo, 32)], - } as const - if (memo) - return { - functionName: 'transferWithMemo', - args: [to, amount, Hex.padLeft(memo, 32)], - } as const - if (from) - return { - functionName: 'transferFrom', - args: [from, to, amount], - } as const - return { - functionName: 'transfer', - args: [to, amount], - } as const - })() - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - ...callArgs, - }) - } - - /** - * Extracts the event from the logs. - * - * @param logs - Logs. - * @returns The event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'Transfer', - }) - if (!log) throw new Error('`Transfer` event not found.') - return log - } -} - -/** - * Transfers TIP20 tokens to another address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.transferSync(client, { - * to: '0x...', - * amount: 100n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function transferSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: transferSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await transfer.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = transfer.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace transferSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = transfer.Parameters - - export type Args = transfer.Args - - export type ReturnValue = GetEventArgs< - typeof Abis.tip20, - 'Transfer', - { IndexedOnly: false; Required: true } - > & { - receipt: TransactionReceipt - } - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Unpauses a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.unpause(client, { - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function unpause< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: unpause.Parameters, -): Promise { - return unpause.inner(writeContract, client, parameters) -} - -export namespace unpause { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: unpause.Parameters, - ): Promise> { - const { token, ...rest } = parameters - const call = unpause.call({ token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `unpause` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.unpause.call({ - * token: '0x20c0...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'unpause', - args: [], - }) - } - - /** - * Extracts the event from the logs. - * - * @param logs - Logs. - * @returns The event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'PauseStateUpdate', - }) - if (!log) throw new Error('`PauseStateUpdate` event not found.') - return log - } -} - -/** - * Unpauses a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.unpauseSync(client, { - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function unpauseSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: unpauseSync.Parameters, -): Promise { - const { throwOnReceiptRevert = true, ...rest } = parameters - const receipt = await unpause.inner(writeContractSync, client, { - ...rest, - throwOnReceiptRevert, - } as never) - const { args } = unpause.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace unpauseSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = unpause.Parameters - - export type Args = unpause.Args - - export type ReturnValue = GetEventArgs< - typeof Abis.tip20, - 'PauseStateUpdate', - { IndexedOnly: false; Required: true } - > & { - receipt: TransactionReceipt - } - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Updates the quote token for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.prepareUpdateQuoteToken(client, { - * token: '0x...', - * quoteToken: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function prepareUpdateQuoteToken< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: prepareUpdateQuoteToken.Parameters, -): Promise { - return prepareUpdateQuoteToken.inner(writeContract, client, parameters) -} - -export namespace prepareUpdateQuoteToken { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** New quote token address. */ - quoteToken: TokenId.TokenIdOrAddress - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: prepareUpdateQuoteToken.Parameters, - ): Promise> { - const { quoteToken, token, ...rest } = parameters - const call = prepareUpdateQuoteToken.call({ quoteToken, token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `prepareUpdateQuoteToken` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.prepareUpdateQuoteToken.call({ - * token: '0x20c0...babe', - * quoteToken: '0x20c0...cafe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token, quoteToken } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'setNextQuoteToken', - args: [TokenId.toAddress(quoteToken)], - }) - } - - /** - * Extracts the event from the logs. - * - * @param logs - Logs. - * @returns The event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'NextQuoteTokenSet', - }) - if (!log) throw new Error('`NextQuoteTokenSet` event not found.') - return log - } -} - -/** - * Updates the quote token for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.prepareUpdateQuoteTokenSync(client, { - * token: '0x...', - * quoteToken: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function prepareUpdateQuoteTokenSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: prepareUpdateQuoteTokenSync.Parameters, -): Promise { - const receipt = await prepareUpdateQuoteToken.inner( - writeContractSync, - client, - parameters, - ) - const { args } = prepareUpdateQuoteToken.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace prepareUpdateQuoteTokenSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = prepareUpdateQuoteToken.Parameters - - export type Args = prepareUpdateQuoteToken.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip20, - 'NextQuoteTokenSet', - { - IndexedOnly: false - Required: true - } - > & { - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Updates the quote token for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.updateQuoteToken(client, { - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ -export async function updateQuoteToken< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: updateQuoteToken.Parameters, -): Promise { - return updateQuoteToken.inner(writeContract, client, parameters) -} - -export namespace updateQuoteToken { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = WriteParameters & Args - - export type Args = { - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WriteContractReturnType - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType - - /** @internal */ - export async function inner< - action extends typeof writeContract | typeof writeContractSync, - chain extends Chain | undefined, - account extends Account | undefined, - >( - action: action, - client: Client, - parameters: updateQuoteToken.Parameters, - ): Promise> { - const { token, ...rest } = parameters - const call = updateQuoteToken.call({ token }) - return (await action(client, { - ...rest, - ...call, - } as never)) as never - } - - /** - * Defines a call to the `updateQuoteToken` function. - * - * Can be passed as a parameter to: - * - [`estimateContractGas`](https://viem.sh/docs/contract/estimateContractGas): estimate the gas cost of the call - * - [`simulateContract`](https://viem.sh/docs/contract/simulateContract): simulate the call - * - [`sendCalls`](https://viem.sh/docs/actions/wallet/sendCalls): send multiple calls - * - * @example - * ```ts - * import { createClient, http, walletActions } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(walletActions) - * - * const { result } = await client.sendCalls({ - * calls: [ - * actions.token.updateQuoteToken.call({ - * token: '0x20c0...babe', - * }), - * ] - * }) - * ``` - * - * @param args - Arguments. - * @returns The call. - */ - export function call(args: Args) { - const { token } = args - return defineCall({ - address: TokenId.toAddress(token), - abi: Abis.tip20, - functionName: 'completeQuoteTokenUpdate', - args: [], - }) - } - - /** - * Extracts the event from the logs. - * - * @param logs - Logs. - * @returns The event. - */ - export function extractEvent(logs: Log[]) { - const [log] = parseEventLogs({ - abi: Abis.tip20, - logs, - eventName: 'QuoteTokenUpdate', - }) - if (!log) throw new Error('`QuoteTokenUpdateCompleted` event not found.') - return log - } -} - -/** - * Updates the quote token for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * import { privateKeyToAccount } from 'viem/accounts' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const result = await Actions.token.updateQuoteTokenSync(client, { - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ -export async function updateQuoteTokenSync< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: updateQuoteTokenSync.Parameters, -): Promise { - const receipt = await updateQuoteToken.inner( - writeContractSync, - client, - parameters, - ) - const { args } = updateQuoteToken.extractEvent(receipt.logs) - return { - ...args, - receipt, - } as never -} - -export namespace updateQuoteTokenSync { - export type Parameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, - > = updateQuoteToken.Parameters - - export type Args = updateQuoteToken.Args - - export type ReturnValue = Compute< - GetEventArgs< - typeof Abis.tip20, - 'QuoteTokenUpdate', - { - IndexedOnly: false - Required: true - } - > & { - receipt: TransactionReceipt - } - > - - // TODO: exhaustive error type - export type ErrorType = BaseErrorType -} - -/** - * Watches for TIP20 token approval events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.token.watchApprove(client, { - * onApproval: (args, log) => { - * console.log('Approval:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchApprove< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchApprove.Parameters, -) { - const { onApproval, token, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: TokenId.toAddress(token), - abi: Abis.tip20, - eventName: 'Approval', - onLogs: (logs) => { - for (const log of logs) onApproval(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchApprove { - export type Args = GetEventArgs< - typeof Abis.tip20, - 'Approval', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when tokens are approved. */ - onApproval: (args: Args, log: Log) => void - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } -} - -/** - * Watches for TIP20 token burn events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.token.watchBurn(client, { - * onBurn: (args, log) => { - * console.log('Burn:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchBurn< - chain extends Chain | undefined, - account extends Account | undefined, ->(client: Client, parameters: watchBurn.Parameters) { - const { onBurn, token, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: TokenId.toAddress(token), - abi: Abis.tip20, - eventName: 'Burn', - onLogs: (logs) => { - for (const log of logs) onBurn(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchBurn { - export type Args = GetEventArgs< - typeof Abis.tip20, - 'Burn', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when tokens are burned. */ - onBurn: (args: Args, log: Log) => void - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } -} - -/** - * Watches for new TIP20 tokens created. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.token.watchCreate(client, { - * onTokenCreated: (args, log) => { - * console.log('Token created:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchCreate< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchCreate.Parameters, -) { - const { onTokenCreated, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: Addresses.tip20Factory, - abi: Abis.tip20Factory, - eventName: 'TokenCreated', - onLogs: (logs) => { - for (const log of logs) onTokenCreated(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchCreate { - export type Args = GetEventArgs< - typeof Abis.tip20Factory, - 'TokenCreated', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters< - typeof Abis.tip20Factory, - 'TokenCreated', - true - >, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a new TIP20 token is created. */ - onTokenCreated: (args: Args, log: Log) => void - } -} - -/** - * Watches for TIP20 token mint events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.token.watchMint(client, { - * onMint: (args, log) => { - * console.log('Mint:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchMint< - chain extends Chain | undefined, - account extends Account | undefined, ->(client: Client, parameters: watchMint.Parameters) { - const { onMint, token, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: TokenId.toAddress(token), - abi: Abis.tip20, - eventName: 'Mint', - onLogs: (logs) => { - for (const log of logs) onMint(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchMint { - export type Args = GetEventArgs< - typeof Abis.tip20, - 'Mint', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when tokens are minted. */ - onMint: (args: Args, log: Log) => void - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } - - export type ReturnValue = WatchContractEventReturnType -} - -/** - * Watches for TIP20 token role admin updates. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.token.watchAdminRole(client, { - * onRoleAdminUpdated: (args, log) => { - * console.log('Role admin updated:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchAdminRole< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchAdminRole.Parameters, -) { - const { onRoleAdminUpdated, token, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: TokenId.toAddress(token), - abi: Abis.tip20, - eventName: 'RoleAdminUpdated', - onLogs: (logs) => { - for (const log of logs) onRoleAdminUpdated(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchAdminRole { - export type Args = GetEventArgs< - typeof Abis.tip20, - 'RoleAdminUpdated', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a role admin is updated. */ - onRoleAdminUpdated: (args: Args, log: Log) => void - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } -} - -/** - * Watches for TIP20 token role membership updates. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.token.watchRole(client, { - * onRoleUpdated: (args, log) => { - * console.log('Role updated:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchRole< - chain extends Chain | undefined, - account extends Account | undefined, ->(client: Client, parameters: watchRole.Parameters) { - const { onRoleUpdated, token, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: TokenId.toAddress(token), - abi: Abis.tip20, - eventName: 'RoleMembershipUpdated', - onLogs: (logs) => { - for (const log of logs) { - const type = log.args.hasRole ? 'granted' : 'revoked' - onRoleUpdated({ ...log.args, type }, log) - } - }, - strict: true, - }) -} - -export declare namespace watchRole { - export type Args = GetEventArgs< - typeof Abis.tip20, - 'RoleMembershipUpdated', - { IndexedOnly: false; Required: true } - > & { - /** Type of role update. */ - type: 'granted' | 'revoked' - } - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters< - typeof Abis.tip20, - 'RoleMembershipUpdated', - true - >, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a role membership is updated. */ - onRoleUpdated: (args: Args, log: Log) => void - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } -} - -/** - * Watches for TIP20 token transfer events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.token.watchTransfer(client, { - * onTransfer: (args, log) => { - * console.log('Transfer:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchTransfer< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchTransfer.Parameters, -) { - const { onTransfer, token, ...rest } = parameters - return watchContractEvent(client, { - ...rest, - address: TokenId.toAddress(token), - abi: Abis.tip20, - eventName: 'Transfer', - onLogs: (logs) => { - for (const log of logs) onTransfer(log.args, log) - }, - strict: true, - }) -} - -export declare namespace watchTransfer { - export type Args = GetEventArgs< - typeof Abis.tip20, - 'Transfer', - { IndexedOnly: false; Required: true } - > - - export type Log = viem_Log< - bigint, - number, - false, - ExtractAbiItem, - true - > - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when tokens are transferred. */ - onTransfer: (args: Args, log: Log) => void - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } -} - -/** - * Watches for TIP20 token quote token update events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }) - * - * const unwatch = actions.token.watchUpdateQuoteToken(client, { - * onUpdateQuoteToken: (args, log) => { - * if (args.completed) - * console.log('quote token update completed:', args.newQuoteToken) - * else - * console.log('quote token update proposed:', args.newQuoteToken) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchUpdateQuoteToken< - chain extends Chain | undefined, - account extends Account | undefined, ->( - client: Client, - parameters: watchUpdateQuoteToken.Parameters, -) { - const { onUpdateQuoteToken, token, ...rest } = parameters - const address = TokenId.toAddress(token) - - return watchContractEvent(client, { - ...rest, - address, - abi: Abis.tip20, - onLogs: ( - logs: viem_Log< - bigint, - number, - false, - ExtractAbiItem< - typeof Abis.tip20, - 'NextQuoteTokenSet' | 'QuoteTokenUpdate' - >, - true - >[], - ) => { - for (const log of logs) { - if ( - log.eventName !== 'NextQuoteTokenSet' && - log.eventName !== 'QuoteTokenUpdate' - ) - continue - - onUpdateQuoteToken( - { - ...log.args, - completed: log.eventName === 'QuoteTokenUpdate', - }, - log, - ) - } - }, - strict: true, - } as never) -} - -export declare namespace watchUpdateQuoteToken { - export type Args = OneOf< - | GetEventArgs< - typeof Abis.tip20, - 'NextQuoteTokenSet', - { IndexedOnly: false; Required: true } - > - | GetEventArgs< - typeof Abis.tip20, - 'QuoteTokenUpdate', - { IndexedOnly: false; Required: true } - > - > & { - /** Whether the update has been completed. */ - completed: boolean - } - - export type Log = viem_Log - - export type Parameters = UnionOmit< - WatchContractEventParameters, - 'abi' | 'address' | 'batch' | 'eventName' | 'onLogs' | 'strict' - > & { - /** Callback to invoke when a quote token update is proposed or completed. */ - onUpdateQuoteToken: (args: Args, log: Log) => void - /** Address or ID of the TIP20 token. */ - token: TokenId.TokenIdOrAddress - } -} diff --git a/src/viem/Addresses.ts b/src/viem/Addresses.ts deleted file mode 100644 index 44052dca..00000000 --- a/src/viem/Addresses.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const accountImplementation = - '0x7702c00000000000000000000000000000000000' -export const accountRegistrar = '0x7702ac0000000000000000000000000000000000' -export const feeManager = '0xfeec000000000000000000000000000000000000' -export const nonceManager = '0x4e4F4E4345000000000000000000000000000000' -export const pathUsd = '0x20c0000000000000000000000000000000000000' -export const stablecoinExchange = '0xdec0000000000000000000000000000000000000' -export const tip20Factory = '0x20fc000000000000000000000000000000000000' -export const tip403Registry = '0x403c000000000000000000000000000000000000' diff --git a/src/viem/Chain.bench-d.ts b/src/viem/Chain.bench-d.ts deleted file mode 100644 index 1ce6bdc2..00000000 --- a/src/viem/Chain.bench-d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { attest } from '@ark/attest' -import { createClient, http } from 'viem' -import { test } from 'vitest' -import { tempo } from '../chains.js' - -test('decorator', () => { - createClient({ - chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }), - transport: http('https://cloudflare-eth.com'), - }) - attest.instantiations([62236, 'instantiations']) -}) diff --git a/src/viem/Chain.test.ts b/src/viem/Chain.test.ts deleted file mode 100644 index 808da547..00000000 --- a/src/viem/Chain.test.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { - getTransaction, - prepareTransactionRequest, - sendTransactionSync, -} from 'viem/actions' -import { describe, expect, test, vi } from 'vitest' -import { chain, client, clientWithAccount } from '../../test/viem/config.js' - -describe('chain.prepareTransactionRequest', () => { - test('behavior: sequential nonce keys for feePayer transactions', async () => { - const requests = await Promise.all([ - chain.prepareTransactionRequest({ feePayer: true } as never), - chain.prepareTransactionRequest({ feePayer: true } as never), - chain.prepareTransactionRequest({ feePayer: true } as never), - ]) - - expect((requests[0] as any)?.nonceKey).toBe(undefined) - expect((requests[1] as any)?.nonceKey).toBeGreaterThan(0n) - expect((requests[2] as any)?.nonceKey).toBeGreaterThan(0n) - }) - - test('behavior: nonce key counter resets after event loop tick', async () => { - const requests1 = await Promise.all([ - chain.prepareTransactionRequest({ feePayer: true } as never), - chain.prepareTransactionRequest({ feePayer: true } as never), - ]) - - expect((requests1[0] as any)?.nonceKey).toBe(undefined) - expect((requests1[1] as any)?.nonceKey).toBeGreaterThan(0n) - - // Wait for microtask queue to flush - await new Promise((resolve) => queueMicrotask(() => resolve(undefined))) - - const requests2 = await Promise.all([ - chain.prepareTransactionRequest({ feePayer: true } as never), - chain.prepareTransactionRequest({ feePayer: true } as never), - ]) - - // Counter should have reset - expect((requests2[0] as any)?.nonceKey).toBe(undefined) - expect((requests2[1] as any)?.nonceKey).toBeGreaterThan(0n) - }) - - test('behavior: explicit nonceKey overrides counter', async () => { - const requests = await Promise.all([ - chain.prepareTransactionRequest({ - feePayer: true, - nonceKey: 42n, - } as never), - chain.prepareTransactionRequest({ feePayer: true } as never), - chain.prepareTransactionRequest({ - feePayer: true, - nonceKey: 100n, - } as never), - ]) - - expect((requests[0] as any)?.nonceKey).toBe(42n) - expect((requests[1] as any)?.nonceKey).toBe(undefined) - expect((requests[2] as any)?.nonceKey).toBe(100n) - }) - - test('behavior: default nonceKey when feePayer is not true', async () => { - const request = await chain.prepareTransactionRequest({} as never) - expect((request as any)?.nonceKey).toBe(undefined) - }) - - test('behavior: nonce with sequential nonceKey', async () => { - const requests = await Promise.all([ - chain.prepareTransactionRequest({ feePayer: true } as never), // nonceKey: 0n - chain.prepareTransactionRequest({ feePayer: true } as never), // nonceKey: 1n - chain.prepareTransactionRequest({ feePayer: true } as never), // nonceKey: 2n - ]) - - // Note: 0n is falsy, so first request has nonce undefined - expect((requests[0] as any)?.nonce).toBe(undefined) - expect((requests[0] as any)?.nonceKey).toBe(undefined) - - // nonceKey >= 1n is truthy, so nonce is 0 - expect((requests[1] as any)?.nonce).toBe(0) - expect((requests[1] as any)?.nonceKey).toBeGreaterThan(0n) - - expect((requests[2] as any)?.nonce).toBe(0) - expect((requests[2] as any)?.nonceKey).toBeGreaterThan(0n) - }) - - test('behavior: explicit nonce is preserved', async () => { - const request = await chain.prepareTransactionRequest({ - feePayer: true, - nonce: 123, - } as never) - expect((request as any)?.nonce).toBe(123) - expect((request as any)?.nonceKey).toBe(undefined) - }) - - test('behavior: default nonceKey is 0n (falsy)', async () => { - const request = await chain.prepareTransactionRequest({} as never) - expect((request as any)?.nonceKey).toBe(undefined) - expect((request as any)?.nonce).toBe(undefined) - }) - - test('behavior: resetScheduled optimization - only one microtask scheduled', async () => { - const queueMicrotaskSpy = vi.spyOn(globalThis, 'queueMicrotask') - const callCountBefore = queueMicrotaskSpy.mock.calls.length - - // Prepare multiple transactions in parallel - await Promise.all([ - chain.prepareTransactionRequest({ feePayer: true } as never), - chain.prepareTransactionRequest({ feePayer: true } as never), - chain.prepareTransactionRequest({ feePayer: true } as never), - chain.prepareTransactionRequest({ feePayer: true } as never), - chain.prepareTransactionRequest({ feePayer: true } as never), - ]) - - const callCountAfter = queueMicrotaskSpy.mock.calls.length - - // Only one microtask should have been scheduled for the reset - expect(callCountAfter - callCountBefore).toBe(1) - - queueMicrotaskSpy.mockRestore() - }) - - describe('e2e', async () => { - test('behavior: prepareTransactionRequest', async () => { - const [request, request2, request3] = await Promise.all([ - prepareTransactionRequest(client, { - to: '0x0000000000000000000000000000000000000000', - }), - prepareTransactionRequest(client, { - to: '0x0000000000000000000000000000000000000000', - }), - prepareTransactionRequest(client, { - to: '0x0000000000000000000000000000000000000000', - }), - ]) - expect(request.nonceKey).toBe(undefined) - expect(request2.nonceKey).toBeGreaterThan(0n) - expect(request3.nonceKey).toBeGreaterThan(0n) - }) - - test('behavior: sendTransaction', async () => { - const receipts = await Promise.all([ - sendTransactionSync(clientWithAccount, { - to: '0x0000000000000000000000000000000000000000', - }), - sendTransactionSync(clientWithAccount, { - to: '0x0000000000000000000000000000000000000001', - }), - sendTransactionSync(clientWithAccount, { - to: '0x0000000000000000000000000000000000000002', - }), - ]) - const transactions = await Promise.all([ - getTransaction(clientWithAccount, { - hash: receipts[0].transactionHash, - }), - getTransaction(clientWithAccount, { - hash: receipts[1].transactionHash, - }), - getTransaction(clientWithAccount, { - hash: receipts[2].transactionHash, - }), - ]) - expect(transactions[0].nonceKey).toBe(0n) - expect(transactions[1].nonceKey).toBeGreaterThan(0n) - expect(transactions[2].nonceKey).toBeGreaterThan(0n) - }) - }) -}) diff --git a/src/viem/Chain.ts b/src/viem/Chain.ts deleted file mode 100644 index 5fe34fa7..00000000 --- a/src/viem/Chain.ts +++ /dev/null @@ -1,157 +0,0 @@ -import * as Hex from 'ox/Hex' -import { TokenId } from 'ox/tempo' -import { - defineTransaction, - defineTransactionReceipt, - defineTransactionRequest, - type SerializeTransactionFn, - type Chain as viem_Chain, -} from 'viem' -import type { IsUndefined } from '../internal/types.js' -import * as Formatters from './Formatters.js' -import * as Transaction from './Transaction.js' - -export type Chain< - feeToken extends TokenId.TokenIdOrAddress | null | undefined = - | TokenId.TokenIdOrAddress - | null - | undefined, -> = viem_Chain & - (IsUndefined extends true - ? { - feeToken?: TokenId.TokenIdOrAddress | null | undefined - } - : { - feeToken: feeToken - }) - -function config(chain: chain) { - const nonceKeyManager = { - counter: 0, - resetScheduled: false, - reset() { - this.counter = 0 - this.resetScheduled = false - }, - get() { - if (!this.resetScheduled) { - this.resetScheduled = true - queueMicrotask(() => this.reset()) - } - const count = this.counter - this.counter++ - if (count === 0) return 0n - return Hex.toBigInt(Hex.random(6)) - }, - } - - return { - blockTime: 1_000, - formatters: { - transaction: defineTransaction({ - exclude: ['aaAuthorizationList' as never], - format: Formatters.formatTransaction, - }), - transactionReceipt: defineTransactionReceipt({ - format: Formatters.formatTransactionReceipt, - }), - transactionRequest: defineTransactionRequest({ - format: ( - ...[request, action]: Parameters< - typeof Formatters.formatTransactionRequest - > - ) => - Formatters.formatTransactionRequest( - { - ...request, - - // Note: if we have marked the transaction as intended to be paid - // by a fee payer (feePayer: true), we will not infer the fee token - // as the fee payer will choose their fee token. - ...(request.feePayer !== true && - (action === 'estimateGas' || - action === 'fillTransaction' || - action === 'sendTransaction') - ? { - feeToken: request.feeToken ?? chain.feeToken, - } - : {}), - }, - action, - ), - }), - }, - async prepareTransactionRequest(r) { - const request = r as Transaction.TransactionRequest - const nonceKey = (() => { - if (typeof request.nonceKey !== 'undefined') return request.nonceKey - const nonceKey = nonceKeyManager.get() - if (nonceKey === 0n) return undefined - return nonceKey - })() - - const nonce = (() => { - if (typeof request.nonce === 'number') return request.nonce - // TODO: remove this line once `eth_fillTransaction` supports nonce keys. - if (nonceKey) return 0 - return undefined - })() - - return { ...request, nonce, nonceKey } as unknown as typeof r - }, - serializers: { - // TODO: casting to satisfy viem – viem v3 to have more flexible serializer type. - transaction: ((transaction, signature) => - Transaction.serialize( - { - ...transaction, - // If we have marked the transaction as intended to be paid - // by a fee payer (feePayer: true), we will not infer the fee token - // as the fee payer will choose their fee token. - ...((transaction as { feePayer?: unknown }).feePayer !== true - ? { - feeToken: - (transaction as { feeToken?: unknown }).feeToken ?? - chain.feeToken ?? - undefined, - } - : {}), - } as never, - signature, - )) as SerializeTransactionFn, - }, - ...chain, - } as const satisfies viem_Chain -} - -export function define( - chain: chain, -): define.ReturnValue { - return Object.assign( - (properties = {}) => config({ ...chain, ...properties }), - { id: chain.id }, - ) as never -} - -export { TokenId } - -export declare namespace define { - type Properties = { - /** - * Fee token to set for mutable actions. - * - * Pass `null` to opt-in to protocol preferences. - * - * @example '0x20c0000000000000000000000000000000000001' - * @example 1n - * @example null - */ - feeToken?: TokenId.TokenIdOrAddress | null | undefined - } - - type ReturnValue = (< - properties extends define.Properties | undefined, - >( - properties?: properties | undefined, - ) => ReturnType>) & { id: chain['id'] } -} diff --git a/src/viem/Decorator.bench-d.ts b/src/viem/Decorator.bench-d.ts deleted file mode 100644 index e6766166..00000000 --- a/src/viem/Decorator.bench-d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { attest } from '@ark/attest' -import { createClient, http } from 'viem' -import { test } from 'vitest' -import { decorator } from './Decorator.js' - -test('decorator', () => { - createClient({ - transport: http('https://cloudflare-eth.com'), - }).extend(decorator()) - attest.instantiations([40758, 'instantiations']) -}) diff --git a/src/viem/Decorator.test.ts b/src/viem/Decorator.test.ts deleted file mode 100644 index da8e28a7..00000000 --- a/src/viem/Decorator.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { tempoLocal } from 'tempo.ts/chains' -import { tempoActions } from 'tempo.ts/viem' -import { createClient, http } from 'viem' -import { describe, expect, test } from 'vitest' - -describe('decorator', () => { - const client2 = createClient({ - chain: tempoLocal({ feeToken: 1n }), - transport: http(), - }).extend(tempoActions()) - - test('default', async () => { - expect(Object.keys(client2)).toMatchInlineSnapshot(` - [ - "account", - "batch", - "cacheTime", - "ccipRead", - "chain", - "key", - "name", - "pollingInterval", - "request", - "transport", - "type", - "uid", - "extend", - "verifyHash", - "amm", - "dex", - "faucet", - "fee", - "policy", - "reward", - "token", - ] - `) - }) -}) diff --git a/src/viem/Decorator.ts b/src/viem/Decorator.ts deleted file mode 100644 index 634b6988..00000000 --- a/src/viem/Decorator.ts +++ /dev/null @@ -1,3179 +0,0 @@ -import type { Account, Chain, Client, Transport } from 'viem' -import type { VerifyHashParameters, VerifyHashReturnType } from 'viem/actions' -import type { PartialBy } from '../internal/types.js' -import * as accountActions from './Actions/account.js' -import * as ammActions from './Actions/amm.js' -import * as dexActions from './Actions/dex.js' -import * as faucetActions from './Actions/faucet.js' -import * as feeActions from './Actions/fee.js' -import * as policyActions from './Actions/policy.js' -import * as rewardActions from './Actions/reward.js' -import * as tokenActions from './Actions/token.js' - -export type Decorator< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, -> = { - /** - * Verifies that a signature is valid for a given hash and address. - * Supports Secp256k1, P256, WebCrypto P256, and WebAuthn signatures. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const valid = await client.verifyHash({ - * address: '0x...', - * hash: '0x...', - * signature: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns Whether the signature is valid. - */ - verifyHash: ( - parameters: PartialBy, - ) => Promise - amm: { - /** - * Gets the reserves for a liquidity pool. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c...001' }), - * transport: http(), - * }).extend(tempoActions()) - * - * const pool = await client.amm.getPool({ - * userToken: '0x...', - * validatorToken: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The pool reserves. - */ - getPool: ( - parameters: ammActions.getPool.Parameters, - ) => Promise - /** - * Gets the LP token balance for an account in a specific pool. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const poolId = await client.amm.getPoolId({ - * userToken: '0x...', - * validatorToken: '0x...', - * }) - * - * const balance = await client.amm.getLiquidityBalance({ - * poolId, - * address: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The LP token balance. - */ - getLiquidityBalance: ( - parameters: ammActions.getLiquidityBalance.Parameters, - ) => Promise - /** - * Removes liquidity from a pool. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.amm.burn({ - * userToken: '0x...', - * validatorToken: '0x...', - * liquidity: 50n, - * to: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - burn: ( - parameters: ammActions.burn.Parameters, - ) => Promise - /** - * Removes liquidity from a pool and waits for confirmation. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const { receipt, ...result } = await client.amm.burnSync({ - * userToken: '0x...', - * validatorToken: '0x...', - * liquidity: 50n, - * to: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - burnSync: ( - parameters: ammActions.burnSync.Parameters, - ) => Promise - /** - * Adds liquidity to a pool. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.amm.mint({ - * userTokenAddress: '0x...', - * validatorTokenAddress: '0x...', - * validatorTokenAmount: 100n, - * to: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - mint: ( - parameters: ammActions.mint.Parameters, - ) => Promise - /** - * Adds liquidity to a pool. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.amm.mintSync({ - * userTokenAddress: '0x...', - * validatorTokenAddress: '0x...', - * validatorTokenAmount: 100n, - * to: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - mintSync: ( - parameters: ammActions.mintSync.Parameters, - ) => Promise - /** - * Swaps tokens during a rebalance operation. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.amm.rebalanceSwap({ - * userToken: '0x...', - * validatorToken: '0x...', - * amountOut: 100n, - * to: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - rebalanceSwap: ( - parameters: ammActions.rebalanceSwap.Parameters, - ) => Promise - /** - * Swaps tokens during a rebalance operation and waits for confirmation. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const { receipt, ...result } = await client.amm.rebalanceSwapSync({ - * userToken: '0x...', - * validatorToken: '0x...', - * amountOut: 100n, - * to: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - rebalanceSwapSync: ( - parameters: ammActions.rebalanceSwapSync.Parameters, - ) => Promise - /** - * Watches for burn (liquidity removal) events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.amm.watchBurn({ - * onBurn: (args, log) => { - * console.log('Liquidity removed:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchBurn: (parameters: ammActions.watchBurn.Parameters) => () => void - /** - * Watches for fee swap events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.amm.watchFeeSwap({ - * onFeeSwap: (args, log) => { - * console.log('Fee swap:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchFeeSwap: (parameters: ammActions.watchFeeSwap.Parameters) => () => void - /** - * Watches for liquidity mint events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.amm.watchMint({ - * onMint: (args, log) => { - * console.log('Liquidity added:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchMint: (parameters: ammActions.watchMint.Parameters) => () => void - /** - * Watches for rebalance swap events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.amm.watchRebalanceSwap({ - * onRebalanceSwap: (args, log) => { - * console.log('Rebalance swap:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchRebalanceSwap: ( - parameters: ammActions.watchRebalanceSwap.Parameters, - ) => () => void - } - dex: { - /** - * Buys a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.dex.buy({ - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * amountOut: 100n, - * maxAmountIn: 105n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - buy: ( - parameters: dexActions.buy.Parameters, - ) => Promise - /** - * Buys a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.dex.buySync({ - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * amountOut: 100n, - * maxAmountIn: 105n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt. - */ - buySync: ( - parameters: dexActions.buySync.Parameters, - ) => Promise - /** - * Cancels an order from the orderbook. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.dex.cancel({ - * orderId: 123n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - cancel: ( - parameters: dexActions.cancel.Parameters, - ) => Promise - /** - * Cancels an order from the orderbook. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.dex.cancelSync({ - * orderId: 123n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - cancelSync: ( - parameters: dexActions.cancelSync.Parameters, - ) => Promise - /** - * Creates a new trading pair on the DEX. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.dex.createPair({ - * base: '0x20c...11', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - createPair: ( - parameters: dexActions.createPair.Parameters, - ) => Promise - /** - * Creates a new trading pair on the DEX. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.dex.createPairSync({ - * base: '0x20c...11', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - createPairSync: ( - parameters: dexActions.createPairSync.Parameters, - ) => Promise - /** - * Gets a user's token balance on the DEX. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const balance = await client.dex.getBalance({ - * account: '0x...', - * token: '0x20c...11', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The user's token balance on the DEX. - */ - getBalance: ( - parameters: dexActions.getBalance.Parameters, - ) => Promise - /** - * Gets the quote for buying a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const amountIn = await client.dex.getBuyQuote({ - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * amountOut: 100n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The amount of tokenIn needed to buy the specified amountOut. - */ - getBuyQuote: ( - parameters: dexActions.getBuyQuote.Parameters, - ) => Promise - /** - * Gets an order's details from the orderbook. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const order = await client.dex.getOrder({ - * orderId: 123n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The order details. - */ - getOrder: ( - parameters: dexActions.getOrder.Parameters, - ) => Promise - /** - * Gets the price level information at a specific tick. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const level = await client.dex.getTickLevel({ - * base: '0x20c...11', - * tick: Tick.fromPrice('1.001'), - * isBid: true, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The price level information. - */ - getTickLevel: ( - parameters: dexActions.getTickLevel.Parameters, - ) => Promise - /** - * Gets the quote for selling a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const amountOut = await client.dex.getSellQuote({ - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * amountIn: 100n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The amount of tokenOut received for selling the specified amountIn. - */ - getSellQuote: ( - parameters: dexActions.getSellQuote.Parameters, - ) => Promise - /** - * Places a limit order on the orderbook. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.dex.place({ - * token: '0x20c...11', - * amount: 100n, - * type: 'buy', - * tick: Tick.fromPrice('0.99'), - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - place: ( - parameters: dexActions.place.Parameters, - ) => Promise - /** - * Places a limit order on the orderbook. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.dex.placeSync({ - * token: '0x20c...11', - * amount: 100n, - * type: 'buy', - * tick: Tick.fromPrice('0.99'), - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - placeSync: ( - parameters: dexActions.placeSync.Parameters, - ) => Promise - /** - * Places a flip order that automatically flips when filled. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.dex.placeFlip({ - * token: '0x20c...11', - * amount: 100n, - * type: 'buy', - * tick: Tick.fromPrice('0.99'), - * flipTick: Tick.fromPrice('1.01'), - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - placeFlip: ( - parameters: dexActions.placeFlip.Parameters, - ) => Promise - /** - * Places a flip order that automatically flips when filled. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions, Tick } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.dex.placeFlipSync({ - * token: '0x20c...11', - * amount: 100n, - * type: 'buy', - * tick: Tick.fromPrice('0.99'), - * flipTick: Tick.fromPrice('1.01'), - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - placeFlipSync: ( - parameters: dexActions.placeFlipSync.Parameters, - ) => Promise - /** - * Sells a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.dex.sell({ - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * amountIn: 100n, - * minAmountOut: 95n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - sell: ( - parameters: dexActions.sell.Parameters, - ) => Promise - /** - * Sells a specific amount of tokens. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.dex.sellSync({ - * tokenIn: '0x20c...11', - * tokenOut: '0x20c...20', - * amountIn: 100n, - * minAmountOut: 95n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt. - */ - sellSync: ( - parameters: dexActions.sellSync.Parameters, - ) => Promise - /** - * Withdraws tokens from the DEX to the caller's wallet. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.dex.withdraw({ - * token: '0x20c...11', - * amount: 100n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - withdraw: ( - parameters: dexActions.withdraw.Parameters, - ) => Promise - /** - * Withdraws tokens from the DEX to the caller's wallet. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.dex.withdrawSync({ - * token: '0x20c...11', - * amount: 100n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt. - */ - withdrawSync: ( - parameters: dexActions.withdrawSync.Parameters, - ) => Promise - /** - * Watches for flip order placed events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.dex.watchFlipOrderPlaced({ - * onFlipOrderPlaced: (args, log) => { - * console.log('Flip order placed:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchFlipOrderPlaced: ( - parameters: dexActions.watchFlipOrderPlaced.Parameters, - ) => () => void - /** - * Watches for order cancelled events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.dex.watchOrderCancelled({ - * onOrderCancelled: (args, log) => { - * console.log('Order cancelled:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchOrderCancelled: ( - parameters: dexActions.watchOrderCancelled.Parameters, - ) => () => void - /** - * Watches for order filled events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.dex.watchOrderFilled({ - * onOrderFilled: (args, log) => { - * console.log('Order filled:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchOrderFilled: ( - parameters: dexActions.watchOrderFilled.Parameters, - ) => () => void - /** - * Watches for order placed events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.dex.watchOrderPlaced({ - * onOrderPlaced: (args, log) => { - * console.log('Order placed:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchOrderPlaced: ( - parameters: dexActions.watchOrderPlaced.Parameters, - ) => () => void - } - faucet: { - /** - * Funds an account with an initial amount of set token(s) - * on Tempo's testnet. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hashes = await client.faucet.fund({ - * account: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hashes. - */ - fund: ( - parameters: faucetActions.fund.Parameters, - ) => Promise - } - fee: { - /** - * Gets the user's default fee token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const { address, id } = await client.token.getUserToken() - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - getUserToken: ( - ...parameters: account extends Account - ? [feeActions.getUserToken.Parameters] | [] - : [feeActions.getUserToken.Parameters] - ) => Promise - /** - * Sets the user's default fee token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.setUserToken({ - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - setUserToken: ( - parameters: feeActions.setUserToken.Parameters, - ) => Promise - /** - * Sets the user's default fee token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.fee.setUserTokenSync({ - * token: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - setUserTokenSync: ( - parameters: feeActions.setUserTokenSync.Parameters, - ) => Promise - /** - * Watches for user token set events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.token.watchSetUserToken({ - * onUserTokenSet: (args, log) => { - * console.log('User token set:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchSetUserToken: ( - parameters: feeActions.watchSetUserToken.Parameters, - ) => () => void - } - policy: { - /** - * Creates a new policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.policy.create({ - * admin: '0x...', - * type: 'whitelist', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - create: ( - parameters: policyActions.create.Parameters, - ) => Promise - /** - * Creates a new policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.policy.createSync({ - * admin: '0x...', - * type: 'whitelist', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - createSync: ( - parameters: policyActions.createSync.Parameters, - ) => Promise - /** - * Sets the admin for a policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.policy.setAdmin({ - * policyId: 2n, - * admin: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - setAdmin: ( - parameters: policyActions.setAdmin.Parameters, - ) => Promise - /** - * Sets the admin for a policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.policy.setAdminSync({ - * policyId: 2n, - * admin: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - setAdminSync: ( - parameters: policyActions.setAdminSync.Parameters, - ) => Promise - /** - * Modifies a policy whitelist. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.policy.modifyWhitelist({ - * policyId: 2n, - * address: '0x...', - * allowed: true, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - modifyWhitelist: ( - parameters: policyActions.modifyWhitelist.Parameters, - ) => Promise - /** - * Modifies a policy whitelist. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.policy.modifyWhitelistSync({ - * policyId: 2n, - * address: '0x...', - * allowed: true, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - modifyWhitelistSync: ( - parameters: policyActions.modifyWhitelistSync.Parameters, - ) => Promise - /** - * Modifies a policy blacklist. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.policy.modifyBlacklist({ - * policyId: 2n, - * address: '0x...', - * restricted: true, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - modifyBlacklist: ( - parameters: policyActions.modifyBlacklist.Parameters, - ) => Promise - /** - * Modifies a policy blacklist. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.policy.modifyBlacklistSync({ - * policyId: 2n, - * address: '0x...', - * restricted: true, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - modifyBlacklistSync: ( - parameters: policyActions.modifyBlacklistSync.Parameters, - ) => Promise - /** - * Gets policy data. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const data = await client.policy.getData({ - * policyId: 2n, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The policy data. - */ - getData: ( - parameters: policyActions.getData.Parameters, - ) => Promise - /** - * Checks if a user is authorized by a policy. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const authorized = await client.policy.isAuthorized({ - * policyId: 2n, - * user: '0x...', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns Whether the user is authorized. - */ - isAuthorized: ( - parameters: policyActions.isAuthorized.Parameters, - ) => Promise - /** - * Watches for policy creation events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.policy.watchCreate({ - * onPolicyCreated: (args, log) => { - * console.log('Policy created:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchCreate: ( - parameters: policyActions.watchCreate.Parameters, - ) => () => void - /** - * Watches for policy admin update events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.policy.watchAdminUpdated({ - * onAdminUpdated: (args, log) => { - * console.log('Policy admin updated:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchAdminUpdated: ( - parameters: policyActions.watchAdminUpdated.Parameters, - ) => () => void - /** - * Watches for whitelist update events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.policy.watchWhitelistUpdated({ - * onWhitelistUpdated: (args, log) => { - * console.log('Whitelist updated:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchWhitelistUpdated: ( - parameters: policyActions.watchWhitelistUpdated.Parameters, - ) => () => void - /** - * Watches for blacklist update events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.policy.watchBlacklistUpdated({ - * onBlacklistUpdated: (args, log) => { - * console.log('Blacklist updated:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchBlacklistUpdated: ( - parameters: policyActions.watchBlacklistUpdated.Parameters, - ) => () => void - } - reward: { - /** - * Claims accumulated rewards for a recipient. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.reward.claim({ - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - claim: ( - parameters: rewardActions.claim.Parameters, - ) => Promise - /** - * Claims accumulated rewards for a recipient and waits for confirmation. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.reward.claimSync({ - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The amount claimed and transaction receipt. - */ - claimSync: ( - parameters: rewardActions.claimSync.Parameters, - ) => Promise - /** - * Gets the total reward per second rate for all active streams. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const rate = await client.reward.getTotalPerSecond({ - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The total reward per second (scaled by 1e18). - */ - getTotalPerSecond: ( - parameters: rewardActions.getTotalPerSecond.Parameters, - ) => Promise - /** - * Gets the reward information for a specific account. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const info = await client.reward.getUserRewardInfo({ - * token: '0x20c0000000000000000000000000000000000001', - * account: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The user's reward information (recipient, rewardPerToken, rewardBalance). - */ - getUserRewardInfo: ( - parameters: rewardActions.getUserRewardInfo.Parameters, - ) => Promise - /** - * Sets or changes the reward recipient for a token holder. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.reward.setRecipient({ - * recipient: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - setRecipient: ( - parameters: rewardActions.setRecipient.Parameters, - ) => Promise - /** - * Sets or changes the reward recipient for a token holder and waits for confirmation. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.reward.setRecipientSync({ - * recipient: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - setRecipientSync: ( - parameters: rewardActions.setRecipientSync.Parameters, - ) => Promise - /** - * Starts a new reward stream that distributes tokens to opted-in holders. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.reward.start({ - * amount: 100000000000000000000n, - * seconds: 86400, - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction hash. - */ - start: ( - parameters: rewardActions.start.Parameters, - ) => Promise - /** - * Starts a new reward stream that distributes tokens to opted-in holders and waits for confirmation. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.reward.startSync({ - * amount: 100000000000000000000n, - * seconds: 86400, - * token: '0x20c0000000000000000000000000000000000001', - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - startSync: ( - parameters: rewardActions.startSync.Parameters, - ) => Promise - /** - * Watches for reward recipient set events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.reward.watchRewardRecipientSet({ - * token: '0x20c0000000000000000000000000000000000001', - * onRewardRecipientSet: (args, log) => { - * console.log('Reward recipient set:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchRewardRecipientSet: ( - parameters: rewardActions.watchRewardRecipientSet.Parameters, - ) => () => void - /** - * Watches for reward scheduled events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.reward.watchRewardScheduled({ - * token: '0x20c0000000000000000000000000000000000001', - * onRewardScheduled: (args, log) => { - * console.log('Reward scheduled:', args) - * }, - * }) - * ``` - * - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchRewardScheduled: ( - parameters: rewardActions.watchRewardScheduled.Parameters, - ) => () => void - } - token: { - /** - * Approves a spender to transfer TIP20 tokens on behalf of the caller. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.approve({ - * spender: '0x...', - * amount: 100n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - approve: ( - parameters: tokenActions.approve.Parameters, - ) => Promise - /** - * Approves a spender to transfer TIP20 tokens on behalf of the caller. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.approveSync({ - * spender: '0x...', - * amount: 100n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - approveSync: ( - parameters: tokenActions.approveSync.Parameters, - ) => Promise - /** - * Burns TIP20 tokens from a blocked address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.burnBlocked({ - * from: '0x...', - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - burnBlocked: ( - parameters: tokenActions.burnBlocked.Parameters, - ) => Promise - /** - * Burns TIP20 tokens from a blocked address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.burnBlockedSync({ - * from: '0x...', - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - burnBlockedSync: ( - parameters: tokenActions.burnBlockedSync.Parameters, - ) => Promise - /** - * Burns TIP20 tokens from the caller's balance. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.burn({ - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - burn: ( - parameters: tokenActions.burn.Parameters, - ) => Promise - /** - * Burns TIP20 tokens from the caller's balance. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.burnSync({ - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - burnSync: ( - parameters: tokenActions.burnSync.Parameters, - ) => Promise - /** - * Changes the transfer policy ID for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.changeTransferPolicy({ - * token: '0x...', - * policyId: 1n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - changeTransferPolicy: ( - parameters: tokenActions.changeTransferPolicy.Parameters, - ) => Promise - /** - * Changes the transfer policy ID for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.changeTransferPolicySync({ - * token: '0x...', - * policyId: 1n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - changeTransferPolicySync: ( - parameters: tokenActions.changeTransferPolicySync.Parameters< - chain, - account - >, - ) => Promise - /** - * Creates a new TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const { hash, id, address } = await client.token.create({ - * name: 'My Token', - * symbol: 'MTK', - * currency: 'USD', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - create: ( - parameters: tokenActions.create.Parameters, - ) => Promise - /** - * Creates a new TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.createSync({ - * name: 'My Token', - * symbol: 'MTK', - * currency: 'USD', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - createSync: ( - parameters: tokenActions.createSync.Parameters, - ) => Promise - /** - * Gets TIP20 token allowance. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const allowance = await client.token.getAllowance({ - * spender: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The token allowance. - */ - getAllowance: ( - parameters: tokenActions.getAllowance.Parameters, - ) => Promise - /** - * Gets TIP20 token balance for an address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const balance = await client.token.getBalance() - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The token balance. - */ - getBalance: ( - parameters: tokenActions.getBalance.Parameters, - ) => Promise - /** - * Gets TIP20 token metadata including name, symbol, currency, decimals, and total supply. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const metadata = await client.token.getMetadata({ - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The token metadata. - */ - getMetadata: ( - parameters: tokenActions.getMetadata.Parameters, - ) => Promise - /** - * Gets the admin role for a specific role in a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const adminRole = await client.token.getRoleAdmin({ - * role: 'issuer', - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The admin role hash. - */ - getRoleAdmin: ( - parameters: tokenActions.getRoleAdmin.Parameters, - ) => Promise - /** - * Checks if an account has a specific role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hasRole = await client.token.hasRole({ - * token: '0x...', - * role: 'issuer', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns Whether the account has the role. - */ - hasRole: ( - parameters: tokenActions.hasRole.Parameters, - ) => Promise - /** - * Grants a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.grantRoles({ - * token: '0x...', - * to: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - grantRoles: ( - parameters: tokenActions.grantRoles.Parameters, - ) => Promise - /** - * Grants a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.grantRolesSync({ - * token: '0x...', - * to: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - grantRolesSync: ( - parameters: tokenActions.grantRolesSync.Parameters, - ) => Promise - /** - * Mints TIP20 tokens to an address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.mint({ - * to: '0x...', - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - mint: ( - parameters: tokenActions.mint.Parameters, - ) => Promise - /** - * Mints TIP20 tokens to an address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.mintSync({ - * to: '0x...', - * amount: 100n, - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - mintSync: ( - parameters: tokenActions.mintSync.Parameters, - ) => Promise - /** - * Pauses a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.pause({ - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - pause: ( - parameters: tokenActions.pause.Parameters, - ) => Promise - /** - * Pauses a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.pauseSync({ - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - pauseSync: ( - parameters: tokenActions.pauseSync.Parameters, - ) => Promise - /** - * Renounces a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.renounceRoles({ - * token: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - renounceRoles: ( - parameters: tokenActions.renounceRoles.Parameters, - ) => Promise - /** - * Renounces a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.renounceRolesSync({ - * token: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - renounceRolesSync: ( - parameters: tokenActions.renounceRolesSync.Parameters, - ) => Promise - /** - * Revokes a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.revokeRoles({ - * token: '0x...', - * from: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - revokeRoles: ( - parameters: tokenActions.revokeRoles.Parameters, - ) => Promise - /** - * Revokes a role for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.revokeRolesSync({ - * token: '0x...', - * from: '0x...', - * roles: ['issuer'], - * }) - * ``` - * - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - revokeRolesSync: ( - parameters: tokenActions.revokeRolesSync.Parameters, - ) => Promise - /** - * Sets the supply cap for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.setSupplyCap({ - * token: '0x...', - * supplyCap: 1000000n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - setSupplyCap: ( - parameters: tokenActions.setSupplyCap.Parameters, - ) => Promise - /** - * Sets the supply cap for a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.setSupplyCapSync({ - * token: '0x...', - * supplyCap: 1000000n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - setSupplyCapSync: ( - parameters: tokenActions.setSupplyCapSync.Parameters, - ) => Promise - /** - * Sets the admin role for a specific role in a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.setRoleAdmin({ - * token: '0x...', - * role: 'issuer', - * adminRole: 'admin', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - setRoleAdmin: ( - parameters: tokenActions.setRoleAdmin.Parameters, - ) => Promise - /** - * Sets the admin role for a specific role in a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.setRoleAdminSync({ - * token: '0x...', - * role: 'issuer', - * adminRole: 'admin', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - setRoleAdminSync: ( - parameters: tokenActions.setRoleAdminSync.Parameters, - ) => Promise - /** - * Transfers TIP20 tokens to another address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.transfer({ - * to: '0x...', - * amount: 100n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - transfer: ( - parameters: tokenActions.transfer.Parameters, - ) => Promise - /** - * Transfers TIP20 tokens to another address. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.transferSync({ - * to: '0x...', - * amount: 100n, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - transferSync: ( - parameters: tokenActions.transferSync.Parameters, - ) => Promise - /** - * Unpauses a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const hash = await client.token.unpause({ - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction hash. - */ - unpause: ( - parameters: tokenActions.unpause.Parameters, - ) => Promise - /** - * Unpauses a TIP20 token. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { privateKeyToAccount } from 'viem/accounts' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * account: privateKeyToAccount('0x...'), - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const result = await client.token.unpauseSync({ - * token: '0x...', - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns The transaction receipt and event data. - */ - unpauseSync: ( - parameters: tokenActions.unpauseSync.Parameters, - ) => Promise - /** - * Watches for TIP20 token approval events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.token.watchApprove({ - * onApproval: (args, log) => { - * console.log('Approval:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchApprove: ( - parameters: tokenActions.watchApprove.Parameters, - ) => () => void - /** - * Watches for TIP20 token burn events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.token.watchBurn({ - * onBurn: (args, log) => { - * console.log('Burn:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchBurn: (parameters: tokenActions.watchBurn.Parameters) => () => void - /** - * Watches for new TIP20 tokens created. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.token.watchCreate({ - * onTokenCreated: (args, log) => { - * console.log('Token created:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchCreate: (parameters: tokenActions.watchCreate.Parameters) => () => void - /** - * Watches for TIP20 token mint events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.token.watchMint({ - * onMint: (args, log) => { - * console.log('Mint:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchMint: (parameters: tokenActions.watchMint.Parameters) => () => void - /** - * Watches for TIP20 token role admin updates. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.token.watchAdminRole({ - * onRoleAdminUpdated: (args, log) => { - * console.log('Role admin updated:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchAdminRole: ( - parameters: tokenActions.watchAdminRole.Parameters, - ) => () => void - /** - * Watches for TIP20 token role membership updates. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.token.watchRole({ - * onRoleUpdated: (args, log) => { - * console.log('Role updated:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchRole: (parameters: tokenActions.watchRole.Parameters) => () => void - /** - * Watches for TIP20 token transfer events. - * - * @example - * ```ts - * import { createClient, http } from 'viem' - * import { tempo } from 'tempo.ts/chains' - * import { tempoActions } from 'tempo.ts/viem' - * - * const client = createClient({ - * chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }) - * transport: http(), - * }).extend(tempoActions()) - * - * const unwatch = client.token.watchTransfer({ - * onTransfer: (args, log) => { - * console.log('Transfer:', args) - * }, - * }) - * ``` - * - * @param client - Client. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ - watchTransfer: ( - parameters: tokenActions.watchTransfer.Parameters, - ) => () => void - } -} - -export function decorator() { - return < - transport extends Transport, - chain extends Chain | undefined, - account extends Account | undefined, - >( - client: Client, - ): Decorator => { - return { - verifyHash: (parameters) => accountActions.verifyHash(client, parameters), - amm: { - getPool: (parameters) => ammActions.getPool(client, parameters), - getLiquidityBalance: (parameters) => - ammActions.getLiquidityBalance(client, parameters), - burn: (parameters) => ammActions.burn(client, parameters), - burnSync: (parameters) => ammActions.burnSync(client, parameters), - mint: (parameters) => ammActions.mint(client, parameters), - mintSync: (parameters) => ammActions.mintSync(client, parameters), - rebalanceSwap: (parameters) => - ammActions.rebalanceSwap(client, parameters), - rebalanceSwapSync: (parameters) => - ammActions.rebalanceSwapSync(client, parameters), - watchBurn: (parameters) => ammActions.watchBurn(client, parameters), - watchFeeSwap: (parameters) => - ammActions.watchFeeSwap(client, parameters), - watchMint: (parameters) => ammActions.watchMint(client, parameters), - watchRebalanceSwap: (parameters) => - ammActions.watchRebalanceSwap(client, parameters), - }, - dex: { - buy: (parameters) => dexActions.buy(client, parameters), - buySync: (parameters) => dexActions.buySync(client, parameters), - cancel: (parameters) => dexActions.cancel(client, parameters), - cancelSync: (parameters) => dexActions.cancelSync(client, parameters), - createPair: (parameters) => dexActions.createPair(client, parameters), - createPairSync: (parameters) => - dexActions.createPairSync(client, parameters), - getBalance: (parameters) => dexActions.getBalance(client, parameters), - getBuyQuote: (parameters) => dexActions.getBuyQuote(client, parameters), - getOrder: (parameters) => dexActions.getOrder(client, parameters), - getTickLevel: (parameters) => - dexActions.getTickLevel(client, parameters), - getSellQuote: (parameters) => - dexActions.getSellQuote(client, parameters), - place: (parameters) => dexActions.place(client, parameters), - placeSync: (parameters) => dexActions.placeSync(client, parameters), - placeFlip: (parameters) => dexActions.placeFlip(client, parameters), - placeFlipSync: (parameters) => - dexActions.placeFlipSync(client, parameters), - sell: (parameters) => dexActions.sell(client, parameters), - sellSync: (parameters) => dexActions.sellSync(client, parameters), - withdraw: (parameters) => dexActions.withdraw(client, parameters), - withdrawSync: (parameters) => - dexActions.withdrawSync(client, parameters), - watchFlipOrderPlaced: (parameters) => - dexActions.watchFlipOrderPlaced(client, parameters), - watchOrderCancelled: (parameters) => - dexActions.watchOrderCancelled(client, parameters), - watchOrderFilled: (parameters) => - dexActions.watchOrderFilled(client, parameters), - watchOrderPlaced: (parameters) => - dexActions.watchOrderPlaced(client, parameters), - }, - faucet: { - fund: (parameters) => faucetActions.fund(client, parameters), - }, - fee: { - // @ts-expect-error - getUserToken: (parameters) => - // @ts-expect-error - feeActions.getUserToken(client, parameters), - setUserToken: (parameters) => - feeActions.setUserToken(client, parameters), - setUserTokenSync: (parameters) => - feeActions.setUserTokenSync(client, parameters), - watchSetUserToken: (parameters) => - feeActions.watchSetUserToken(client, parameters), - }, - policy: { - create: (parameters) => policyActions.create(client, parameters), - createSync: (parameters) => - policyActions.createSync(client, parameters), - setAdmin: (parameters) => policyActions.setAdmin(client, parameters), - setAdminSync: (parameters) => - policyActions.setAdminSync(client, parameters), - modifyWhitelist: (parameters) => - policyActions.modifyWhitelist(client, parameters), - modifyWhitelistSync: (parameters) => - policyActions.modifyWhitelistSync(client, parameters), - modifyBlacklist: (parameters) => - policyActions.modifyBlacklist(client, parameters), - modifyBlacklistSync: (parameters) => - policyActions.modifyBlacklistSync(client, parameters), - getData: (parameters) => policyActions.getData(client, parameters), - isAuthorized: (parameters) => - policyActions.isAuthorized(client, parameters), - watchCreate: (parameters) => - policyActions.watchCreate(client, parameters), - watchAdminUpdated: (parameters) => - policyActions.watchAdminUpdated(client, parameters), - watchWhitelistUpdated: (parameters) => - policyActions.watchWhitelistUpdated(client, parameters), - watchBlacklistUpdated: (parameters) => - policyActions.watchBlacklistUpdated(client, parameters), - }, - reward: { - claim: (parameters) => rewardActions.claim(client, parameters), - claimSync: (parameters) => rewardActions.claimSync(client, parameters), - getTotalPerSecond: (parameters) => - rewardActions.getTotalPerSecond(client, parameters), - getUserRewardInfo: (parameters) => - rewardActions.getUserRewardInfo(client, parameters), - setRecipient: (parameters) => - rewardActions.setRecipient(client, parameters), - setRecipientSync: (parameters) => - rewardActions.setRecipientSync(client, parameters), - start: (parameters) => rewardActions.start(client, parameters), - startSync: (parameters) => rewardActions.startSync(client, parameters), - watchRewardRecipientSet: (parameters) => - rewardActions.watchRewardRecipientSet(client, parameters), - watchRewardScheduled: (parameters) => - rewardActions.watchRewardScheduled(client, parameters), - }, - token: { - approve: (parameters) => tokenActions.approve(client, parameters), - approveSync: (parameters) => - tokenActions.approveSync(client, parameters), - burnBlocked: (parameters) => - tokenActions.burnBlocked(client, parameters), - burnBlockedSync: (parameters) => - tokenActions.burnBlockedSync(client, parameters), - burn: (parameters) => tokenActions.burn(client, parameters), - burnSync: (parameters) => tokenActions.burnSync(client, parameters), - changeTransferPolicy: (parameters) => - tokenActions.changeTransferPolicy(client, parameters), - changeTransferPolicySync: (parameters) => - tokenActions.changeTransferPolicySync(client, parameters), - create: (parameters) => tokenActions.create(client, parameters), - createSync: (parameters) => tokenActions.createSync(client, parameters), - getAllowance: (parameters) => - tokenActions.getAllowance(client, parameters), - getBalance: (parameters) => tokenActions.getBalance(client, parameters), - getMetadata: (parameters) => - tokenActions.getMetadata(client, parameters), - getRoleAdmin: (parameters) => - tokenActions.getRoleAdmin(client, parameters), - hasRole: (parameters) => tokenActions.hasRole(client, parameters), - grantRoles: (parameters) => tokenActions.grantRoles(client, parameters), - grantRolesSync: (parameters) => - tokenActions.grantRolesSync(client, parameters), - mint: (parameters) => tokenActions.mint(client, parameters), - mintSync: (parameters) => tokenActions.mintSync(client, parameters), - pause: (parameters) => tokenActions.pause(client, parameters), - pauseSync: (parameters) => tokenActions.pauseSync(client, parameters), - renounceRoles: (parameters) => - tokenActions.renounceRoles(client, parameters), - renounceRolesSync: (parameters) => - tokenActions.renounceRolesSync(client, parameters), - revokeRoles: (parameters) => - tokenActions.revokeRoles(client, parameters), - revokeRolesSync: (parameters) => - tokenActions.revokeRolesSync(client, parameters), - setSupplyCap: (parameters) => - tokenActions.setSupplyCap(client, parameters), - setSupplyCapSync: (parameters) => - tokenActions.setSupplyCapSync(client, parameters), - setRoleAdmin: (parameters) => - tokenActions.setRoleAdmin(client, parameters), - setRoleAdminSync: (parameters) => - tokenActions.setRoleAdminSync(client, parameters), - transfer: (parameters) => tokenActions.transfer(client, parameters), - transferSync: (parameters) => - tokenActions.transferSync(client, parameters), - unpause: (parameters) => tokenActions.unpause(client, parameters), - unpauseSync: (parameters) => - tokenActions.unpauseSync(client, parameters), - watchApprove: (parameters) => - tokenActions.watchApprove(client, parameters), - watchBurn: (parameters) => tokenActions.watchBurn(client, parameters), - watchCreate: (parameters) => - tokenActions.watchCreate(client, parameters), - watchMint: (parameters) => tokenActions.watchMint(client, parameters), - watchAdminRole: (parameters) => - tokenActions.watchAdminRole(client, parameters), - watchRole: (parameters) => tokenActions.watchRole(client, parameters), - watchTransfer: (parameters) => - tokenActions.watchTransfer(client, parameters), - }, - } - } -} diff --git a/src/viem/Formatters.ts b/src/viem/Formatters.ts deleted file mode 100644 index be4ed3c0..00000000 --- a/src/viem/Formatters.ts +++ /dev/null @@ -1,164 +0,0 @@ -// TODO: Find opportunities to make this file less duplicated + more simplified with Viem v3. - -import * as Hex from 'ox/Hex' -import { - Transaction as ox_Transaction, - TransactionRequest as ox_TransactionRequest, -} from 'ox/tempo' -import { - type Chain, - type Account as viem_Account, - formatTransaction as viem_formatTransaction, - formatTransactionReceipt as viem_formatTransactionReceipt, - formatTransactionRequest as viem_formatTransactionRequest, -} from 'viem' -import { type Address, parseAccount } from 'viem/accounts' -import type { UnionOmit } from '../internal/types.js' -import type { Account } from './Account.js' -import type { GetFeeTokenParameter } from './internal/types.js' -import { - isTempo, - type Transaction, - type TransactionReceipt, - type TransactionReceiptRpc, - type TransactionRequest, - type TransactionRequestRpc, - type TransactionRpc, -} from './Transaction.js' - -export function formatTransaction( - transaction: TransactionRpc, -): Transaction { - if (!isTempo(transaction)) return viem_formatTransaction(transaction as never) - - const { - feePayerSignature, - gasPrice: _, - nonce, - ...tx - } = ox_Transaction.fromRpc(transaction as never) as ox_Transaction.Tempo - - return { - ...tx, - accessList: tx.accessList!, - feePayerSignature: feePayerSignature - ? { - r: Hex.fromNumber(feePayerSignature.r, { size: 32 }), - s: Hex.fromNumber(feePayerSignature.s, { size: 32 }), - v: BigInt(feePayerSignature.v ?? 27), - yParity: feePayerSignature.yParity, - } - : undefined, - nonce: Number(nonce), - typeHex: - ox_Transaction.toRpcType[ - tx.type as keyof typeof ox_Transaction.toRpcType - ], - type: tx.type as 'tempo', - } -} - -export function formatTransactionReceipt( - receipt: TransactionReceiptRpc, -): TransactionReceipt { - return viem_formatTransactionReceipt(receipt as never) -} - -type Request = UnionOmit< - TransactionRequest, - 'feeToken' -> & - GetFeeTokenParameter -export function formatTransactionRequest( - r: Request, - action?: string | undefined, -): TransactionRequestRpc { - const request = r as Request & { - account?: viem_Account | Address | undefined - } - const account = request.account - ? parseAccount(request.account) - : undefined - - // Convert EIP-1559 transactions to Tempo transactions. - if (request.type === 'eip1559') (request as any).type = 'tempo' - - // If the request is not a Tempo transaction, route to Viem formatter. - if (!isTempo(request)) - return viem_formatTransactionRequest( - r as never, - action, - ) as TransactionRequestRpc - - if (action) - request.calls = request.calls ?? [ - { - to: - r.to || - (!r.data || r.data === '0x' - ? '0x0000000000000000000000000000000000000000' - : undefined), - value: r.value, - data: r.data, - }, - ] - - const rpc = ox_TransactionRequest.toRpc({ - ...request, - type: 'tempo', - } as never) - - if (action === 'estimateGas') { - rpc.maxFeePerGas = undefined - rpc.maxPriorityFeePerGas = undefined - } - - // JSON-RPC accounts (wallets) don't support Tempo transactions yet, - // we will omit the type to attempt to make them compatible - // with the base transaction structure. - // TODO: `calls` will not be supported by a lot of JSON-RPC accounts (wallet), - // use `wallet_sendCalls` or sequential `eth_sendTransaction` to mimic the - // behavior of `calls`. - if (account?.type === 'json-rpc') { - if (rpc.calls?.length && rpc.calls.length > 1) - throw new Error( - 'Batch calls are not supported with JSON-RPC accounts yet.', - ) - rpc.type = undefined - } - - // We rely on `calls` for Tempo transactions. - // However, `calls` may not be supported by JSON-RPC accounts (wallets) yet, - // so we will not remove the `data`, `to`, and `value` fields to make it - // compatible with the base transaction structure. - if (account?.type !== 'json-rpc') { - rpc.to = undefined - rpc.data = undefined - rpc.value = undefined - } - - const [keyType, keyData] = (() => { - const type = - account && 'keyType' in account ? account.keyType : account?.source - if (!type) return [undefined, undefined] - if (type === 'webAuthn') - // TODO: derive correct bytes size of key data based on webauthn create metadata. - return ['webAuthn', `0x${'ff'.repeat(1400)}`] - if (['p256', 'secp256k1'].includes(type)) return [type, undefined] - return [undefined, undefined] - })() - - return { - ...rpc, - ...(keyType ? { keyType } : {}), - ...(keyData ? { keyData } : {}), - ...(request.feePayer - ? { - feePayer: - typeof request.feePayer === 'object' - ? parseAccount(request.feePayer) - : request.feePayer, - } - : {}), - } as never -} diff --git a/src/viem/P256.ts b/src/viem/P256.ts deleted file mode 100644 index 99e77a4b..00000000 --- a/src/viem/P256.ts +++ /dev/null @@ -1 +0,0 @@ -export { randomPrivateKey } from 'ox/P256' diff --git a/src/viem/Secp256k1.ts b/src/viem/Secp256k1.ts deleted file mode 100644 index e04db5de..00000000 --- a/src/viem/Secp256k1.ts +++ /dev/null @@ -1 +0,0 @@ -export { randomPrivateKey } from 'ox/Secp256k1' diff --git a/src/viem/Storage.ts b/src/viem/Storage.ts deleted file mode 100644 index d502bef8..00000000 --- a/src/viem/Storage.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { createStore, del, get, set } from 'idb-keyval' -import * as Json from 'ox/Json' - -import type { MaybePromise } from '../internal/types.js' -import { normalizeValue } from './internal/utils.js' - -export type Storage< - schema extends Record = Record, -> = { - getItem: ( - name: name, - ) => MaybePromise - removeItem: (name: name) => MaybePromise - setItem: ( - name: name, - value: schema[name], - ) => MaybePromise -} - -export function from>( - storage: Storage, - options: { key?: string | undefined } = {}, -): Storage { - const key = (name: any) => `${options.key ? `${options.key}:` : ''}${name}` - return { - getItem: (name) => storage.getItem(key(name)) as never, - removeItem: (name) => storage.removeItem(key(name)), - setItem: (name, value) => storage.setItem(key(name), value), - } -} - -export namespace from { - export type Options = { - key?: string | undefined - } -} - -export function idb>() { - const store = - typeof indexedDB !== 'undefined' - ? createStore('tempo.ts', 'store') - : undefined - return from({ - async getItem(name) { - const value = await get(name, store) - if (value === null) return null - return value - }, - async removeItem(name) { - await del(name, store) - }, - async setItem(name, value) { - await set(name, normalizeValue(value), store) - }, - }) -} - -export function localStorage>( - options: localStorage.Options = {}, -) { - if (typeof window === 'undefined') return memory() - return from( - { - async getItem(name) { - const item = window.localStorage.getItem(name) - if (item === null) return null - try { - return Json.parse(item) - } catch { - return null - } - }, - async removeItem(name) { - window.localStorage.removeItem(name) - }, - async setItem(name, value) { - window.localStorage.setItem(name, Json.stringify(value)) - }, - }, - options, - ) -} - -export namespace localStorage { - export type Options = from.Options -} - -const store = new Map() -export function memory>( - options: memory.Options = {}, -) { - return from( - { - getItem(name) { - return store.get(name) ?? null - }, - removeItem(name) { - store.delete(name) - }, - setItem(name, value) { - store.set(name, value) - }, - }, - options, - ) -} - -export namespace memory { - export type Options = from.Options -} diff --git a/src/viem/TokenIds.ts b/src/viem/TokenIds.ts deleted file mode 100644 index 0873060e..00000000 --- a/src/viem/TokenIds.ts +++ /dev/null @@ -1 +0,0 @@ -export const pathUsd = 0n diff --git a/src/viem/Transaction.ts b/src/viem/Transaction.ts deleted file mode 100644 index 32f330ea..00000000 --- a/src/viem/Transaction.ts +++ /dev/null @@ -1,382 +0,0 @@ -// TODO: Find opportunities to make this file less duplicated + more simplified with Viem v3. - -import * as Hex from 'ox/Hex' -import * as Secp256k1 from 'ox/Secp256k1' -import * as Signature from 'ox/Signature' -import { - type AuthorizationTempo, - type KeyAuthorization, - type TransactionReceipt as ox_TransactionReceipt, - SignatureEnvelope, - TxEnvelopeTempo as TxTempo, -} from 'ox/tempo' -import { - type AccessList, - type Account, - type Address, - type FeeValuesEIP1559, - type ParseTransactionReturnType, - type TransactionBase, - type TransactionRequestBase, - type TransactionSerializableBase, - type TransactionSerializedGeneric, - getTransactionType as viem_getTransactionType, - parseTransaction as viem_parseTransaction, - type RpcTransaction as viem_RpcTransaction, - type RpcTransactionRequest as viem_RpcTransactionRequest, - type Signature as viem_Signature, - serializeTransaction as viem_serializeTransaction, - type Transaction as viem_Transaction, - type TransactionReceipt as viem_TransactionReceipt, - type TransactionRequest as viem_TransactionRequest, - type TransactionSerializable as viem_TransactionSerializable, - type TransactionSerialized as viem_TransactionSerialized, - type TransactionType as viem_TransactionType, -} from 'viem' -import type { ExactPartial, OneOf, PartialBy } from '../internal/types.js' - -export type Transaction< - bigintType = bigint, - numberType = number, - pending extends boolean = false, -> = OneOf< - | viem_Transaction - | TransactionTempo -> -export type TransactionRpc = OneOf< - | viem_RpcTransaction - | (Omit< - TransactionTempo, - 'authorizationList' | 'keyAuthorization' | 'signature' - > & { - authorizationList?: AuthorizationTempo.ListRpc | undefined - keyAuthorization?: KeyAuthorization.Rpc | null | undefined - signature: SignatureEnvelope.SignatureEnvelopeRpc - }) -> - -export type TransactionTempo< - quantity = bigint, - index = number, - isPending extends boolean = boolean, - type = 'tempo', -> = PartialBy< - Omit< - TransactionBase, - 'data' | 'input' | 'value' | 'to' - >, - 'r' | 's' | 'v' | 'yParity' -> & { - accessList: AccessList - authorizationList?: AuthorizationTempo.ListSigned | undefined - calls: readonly TxTempo.Call[] - chainId: index - feeToken?: Address | undefined - feePayerSignature?: viem_Signature | undefined - keyAuthorization?: KeyAuthorization.Signed | null | undefined - nonceKey?: quantity | undefined - signature: SignatureEnvelope.SignatureEnvelope - type: type - validBefore?: index | undefined - validAfter?: index | undefined -} & FeeValuesEIP1559 - -export type TransactionRequest< - bigintType = bigint, - numberType = number, -> = OneOf< - | viem_TransactionRequest - | TransactionRequestTempo -> -export type TransactionRequestRpc = OneOf< - viem_RpcTransactionRequest | TransactionRequestTempo -> - -export type TransactionReceipt< - quantity = bigint, - index = number, - status = 'success' | 'reverted', - type = TransactionType, -> = viem_TransactionReceipt & { - feePayer?: Address | undefined - feeToken?: Address | undefined -} - -export type TransactionReceiptRpc = TransactionReceipt< - Hex.Hex, - Hex.Hex, - ox_TransactionReceipt.RpcStatus, - ox_TransactionReceipt.RpcType -> - -export type TransactionRequestTempo< - quantity = bigint, - index = number, - type = 'tempo', -> = TransactionRequestBase & - ExactPartial> & { - accessList?: AccessList | undefined - keyAuthorization?: KeyAuthorization.Signed | undefined - calls?: readonly TxTempo.Call[] | undefined - feePayer?: Account | true | undefined - feeToken?: Address | bigint | undefined - nonceKey?: 'random' | quantity | undefined - validBefore?: index | undefined - validAfter?: index | undefined - } - -export type TransactionSerializable = OneOf< - viem_TransactionSerializable | TransactionSerializableTempo -> - -export type TransactionSerializableTempo< - quantity = bigint, - index = number, -> = TransactionSerializableBase & - ExactPartial> & { - accessList?: AccessList | undefined - calls: readonly TxTempo.Call[] - chainId: number - feeToken?: Address | bigint | undefined - feePayerSignature?: viem_Signature | null | undefined - keyAuthorization?: KeyAuthorization.Signed | undefined - nonceKey?: quantity | undefined - signature?: SignatureEnvelope.SignatureEnvelope | undefined - validBefore?: index | undefined - validAfter?: index | undefined - type?: 'tempo' | undefined - } - -export type TransactionSerialized< - type extends TransactionType = TransactionType, -> = viem_TransactionSerialized | TransactionSerializedTempo - -export type TransactionSerializedTempo = `0x76${string}` - -export type TransactionType = viem_TransactionType | 'tempo' - -export function getType( - transaction: Record, -): Transaction['type'] { - if ( - typeof transaction.calls !== 'undefined' || - typeof transaction.feePayer !== 'undefined' || - typeof transaction.feeToken !== 'undefined' || - typeof transaction.nonceKey !== 'undefined' || - typeof transaction.signature !== 'undefined' || - typeof transaction.validBefore !== 'undefined' || - typeof transaction.validAfter !== 'undefined' - ) - return 'tempo' as never - if (transaction.type) return transaction.type as never - return viem_getTransactionType(transaction) as never -} - -export function isTempo(transaction: Record) { - try { - const type = getType(transaction) - return type === 'tempo' - } catch { - return false - } -} - -export function deserialize< - const serialized extends TransactionSerializedGeneric, ->(serializedTransaction: serialized): deserialize.ReturnValue { - const type = Hex.slice(serializedTransaction, 0, 1) - if (type === '0x76') { - const from = - Hex.slice(serializedTransaction, -6) === '0xfeefeefeefee' - ? Hex.slice(serializedTransaction, -26, -6) - : undefined - return { - ...deserializeTempo(serializedTransaction as `0x76${string}`), - from, - } as never - } - return viem_parseTransaction(serializedTransaction) as never -} - -export declare namespace deserialize { - export type ReturnValue< - serialized extends - TransactionSerializedGeneric = TransactionSerializedGeneric, - > = serialized extends TransactionSerializedTempo - ? TransactionSerializableTempo - : ParseTransactionReturnType -} - -export async function serialize( - transaction: TransactionSerializable & { - feePayer?: Account | true | undefined - from?: Address | undefined - }, - signature?: - | OneOf - | undefined, -) { - // If the transaction is not a Tempo transaction, route to Viem serializer. - if (!isTempo(transaction)) { - if (signature && 'type' in signature && signature.type !== 'secp256k1') - throw new Error( - 'Unsupported signature type. Expected `secp256k1` but got `' + - signature.type + - '`.', - ) - if (signature && 'type' in signature) { - const { r, s, yParity } = signature?.signature! - return viem_serializeTransaction(transaction as never, { - r: Hex.fromNumber(r, { size: 32 }), - s: Hex.fromNumber(s, { size: 32 }), - yParity, - }) - } - return viem_serializeTransaction(transaction as never, signature) - } - - const type = getType(transaction) - if (type === 'tempo') - return serializeTempo( - transaction as TransactionSerializableTempo, - signature, - ) - - throw new Error('Unsupported transaction type') -} - -//////////////////////////////////////////////////////////////////////////////////// -// Internal - -/** @internal */ -function deserializeTempo( - serializedTransaction: TransactionSerializedTempo, -): TransactionSerializableTempo { - const { feePayerSignature, nonce, ...tx } = TxTempo.deserialize( - serializedTransaction, - ) - return { - ...tx, - nonce: Number(nonce ?? 0n), - feePayerSignature: feePayerSignature - ? { - r: Hex.fromNumber(feePayerSignature.r, { size: 32 }), - s: Hex.fromNumber(feePayerSignature.s, { size: 32 }), - yParity: feePayerSignature.yParity, - } - : feePayerSignature, - } satisfies TransactionSerializableTempo -} - -/** @internal */ -async function serializeTempo( - transaction: TransactionSerializableTempo & { - feePayer?: Account | true | undefined - from?: Address | undefined - }, - sig?: OneOf | undefined, -) { - const signature = (() => { - if (transaction.signature) return transaction.signature - if (sig && 'type' in sig) return sig as SignatureEnvelope.SignatureEnvelope - if (sig) - return SignatureEnvelope.from({ - r: BigInt(sig.r!), - s: BigInt(sig.s!), - yParity: Number(sig.yParity!), - }) - return undefined - })() - - const { chainId, feePayer, feePayerSignature, nonce, ...rest } = transaction - - const transaction_ox = { - ...rest, - calls: rest.calls?.length - ? rest.calls - : [ - { - to: - rest.to || - (!rest.data || rest.data === '0x' - ? '0x0000000000000000000000000000000000000000' - : undefined), - value: rest.value, - data: rest.data, - }, - ], - chainId: Number(chainId), - feePayerSignature: feePayerSignature - ? { - r: BigInt(feePayerSignature.r!), - s: BigInt(feePayerSignature.s!), - yParity: Number(feePayerSignature.yParity), - } - : feePayer - ? null - : undefined, - type: 'tempo', - ...(nonce ? { nonce: BigInt(nonce) } : {}), - } satisfies TxTempo.TxEnvelopeTempo - - if (signature && typeof transaction.feePayer === 'object') { - const tx = TxTempo.from(transaction_ox, { - signature, - }) - - const sender = (() => { - if (transaction.from) return transaction.from - if (signature.type === 'secp256k1') - return Secp256k1.recoverAddress({ - payload: TxTempo.getSignPayload(tx), - signature: signature.signature, - }) - throw new Error('Unable to extract sender from transaction or signature.') - })() - - const hash = TxTempo.getFeePayerSignPayload(tx, { - sender, - }) - - const feePayerSignature = await transaction.feePayer.sign!({ - hash, - }) - - return TxTempo.serialize(tx, { - feePayerSignature: Signature.from(feePayerSignature), - }) - } - - if (feePayer === true) { - const serialized = TxTempo.serialize(transaction_ox, { - feePayerSignature: null, - signature, - }) - // if the transaction is ready to be sent off (signed), add the sender - // and a fee marker to the serialized transaction, so the fee payer proxy - // can infer the sender address. - if (transaction.from && signature) - return Hex.concat(serialized, transaction.from, '0xfeefeefeefee') - return serialized - } - - return TxTempo.serialize( - // If we have specified a fee payer, the user will not be signing over the fee token. - // Defer the fee token signing to the fee payer. - { ...transaction_ox, ...(feePayer ? { feeToken: undefined } : {}) }, - { - feePayerSignature: undefined, - signature, - }, - ) -} - -// Export types required for inference. -export { - /** @deprecated */ - KeyAuthorization as z_KeyAuthorization, - /** @deprecated */ - SignatureEnvelope as z_SignatureEnvelope, - /** @deprecated */ - TxEnvelopeTempo as z_TxEnvelopeTempo, -} from 'ox/tempo' diff --git a/src/viem/Transport.ts b/src/viem/Transport.ts deleted file mode 100644 index 58871497..00000000 --- a/src/viem/Transport.ts +++ /dev/null @@ -1,191 +0,0 @@ -import * as Address from 'ox/Address' -import * as Hash from 'ox/Hash' -import * as Hex from 'ox/Hex' -import * as Provider from 'ox/Provider' -import * as RpcRequest from 'ox/RpcRequest' -import { createClient, createTransport, type Transport } from 'viem' -import { - getTransactionReceipt, - sendTransaction, - sendTransactionSync, -} from 'viem/actions' -import type * as tempo_Chain from './Chain.js' -import * as Transaction from './Transaction.js' - -export type FeePayer = Transport - -/** - * Creates a fee payer transport that routes requests between - * the default transport or the fee payer transport. - * - * The policy parameter controls how the fee payer handles transactions: - * - `'sign-only'`: Fee payer co-signs the transaction and returns it to the client transport, which then broadcasts it via the default transport - * - `'sign-and-broadcast'`: Fee payer co-signs and broadcasts the transaction directly - * - * @param defaultTransport - The default transport to use. - * @param feePayerTransport - The fee payer transport to use. - * @param parameters - Configuration parameters. - * @returns A relay transport. - */ -export function withFeePayer( - defaultTransport: Transport, - relayTransport: Transport, - parameters?: withFeePayer.Parameters, -): withFeePayer.ReturnValue { - const { policy = 'sign-only' } = parameters ?? {} - - return (config) => { - const transport_default = defaultTransport(config) - const transport_relay = relayTransport(config) - - return createTransport({ - key: withFeePayer.type, - name: 'Relay Proxy', - async request({ method, params }, options) { - if ( - method === 'eth_sendRawTransactionSync' || - method === 'eth_sendRawTransaction' - ) { - const serialized = (params as any)[0] as `0x76${string}` - const transaction = Transaction.deserialize(serialized) - - // If the transaction is intended to be sponsored, forward it to the relay. - if (transaction.feePayerSignature === null) { - // For 'sign-and-broadcast', relay signs and broadcasts - if (policy === 'sign-and-broadcast') - return transport_relay.request( - { method, params }, - options, - ) as never - - // For 'sign-only', request signature from relay using eth_signRawTransaction - { - // Request signature from relay using eth_signRawTransaction - const signedTransaction = await transport_relay.request( - { - method: 'eth_signRawTransaction', - params: [serialized], - }, - options, - ) - - // Broadcast the signed transaction via the default transport - return transport_default.request( - { method, params: [signedTransaction] }, - options, - ) as never - } - } - } - return transport_default.request({ method, params }, options) as never - }, - type: withFeePayer.type, - }) - } -} - -export declare namespace withFeePayer { - export const type = 'feePayer' - - export type Parameters = { - /** Policy for how the fee payer should handle transactions. Defaults to `'sign-only'`. */ - policy?: 'sign-only' | 'sign-and-broadcast' | undefined - } - - export type ReturnValue = FeePayer -} - -/** - * Creates a transport that instruments a compatibility layer for - * `wallet_` RPC actions (`sendCalls`, `getCallsStatus`, etc). - * - * @param transport - Transport to wrap. - * @returns Transport. - */ -export function walletNamespaceCompat(transport: Transport): Transport { - const sendCallsMagic = Hash.keccak256(Hex.fromString('TEMPO_5792')) - - return (options) => { - const t = transport(options) - - const account = options.account - - type Chain = ReturnType> - const chain = options.chain as Chain - - return { - ...t, - async request(args: never) { - const request = RpcRequest.from(args) - - const client = createClient({ - account, - chain, - transport, - }) - - if (request.method === 'wallet_sendCalls') { - const params = request.params[0] ?? {} - const { capabilities, chainId, from } = params - const { sync } = capabilities ?? {} - - if (!account) throw new Provider.DisconnectedError() - if (!chainId) throw new Provider.UnsupportedChainIdError() - if (Number(chainId) !== client.chain.id) - throw new Provider.UnsupportedChainIdError() - if (from && !Address.isEqual(from, account.address)) - throw new Provider.DisconnectedError() - - const calls = (params.calls ?? []).map((call) => ({ - to: call.to, - value: call.value ? BigInt(call.value) : undefined, - data: call.data, - })) - - const hash = await (async () => { - if (!sync) - return sendTransaction(client, { - account, - calls, - }) - - const { transactionHash } = await sendTransactionSync(client, { - account, - calls, - }) - return transactionHash - })() - - const id = Hex.concat(hash, Hex.padLeft(chainId, 32), sendCallsMagic) - - return { - capabilities: { sync }, - id, - } - } - - if (request.method === 'wallet_getCallsStatus') { - const [id] = request.params ?? [] - if (!id) throw new Error('`id` not found') - if (!id.endsWith(sendCallsMagic.slice(2))) - throw new Error('`id` not supported') - Hex.assert(id) - - const hash = Hex.slice(id, 0, 32) - const chainId = Hex.slice(id, 32, 64) - - const receipt = await getTransactionReceipt(client, { hash }) - return { - atomic: true, - chainId: Number(chainId), - receipts: [receipt], - status: receipt.status === 'success' ? 200 : 500, - version: '2.0.0', - } - } - - return t.request(args) - }, - } as never - } -} diff --git a/src/viem/WebAuthnP256.ts b/src/viem/WebAuthnP256.ts deleted file mode 100644 index cd3a232c..00000000 --- a/src/viem/WebAuthnP256.ts +++ /dev/null @@ -1,146 +0,0 @@ -import * as Bytes from 'ox/Bytes' -import type * as Hex from 'ox/Hex' -import * as PublicKey from 'ox/PublicKey' -import * as WebAuthnP256 from 'ox/WebAuthnP256' - -export type P256Credential = { - id: WebAuthnP256.P256Credential['id'] - publicKey: Hex.Hex - raw: WebAuthnP256.P256Credential['raw'] -} - -/** - * Creates a WebAuthn credential (ie. a passkey). - * - * This function returns the credential object, which includes the public key. - * It is recommended to store the public key against the credential in an external store - * as it is not possible to extract a public key from a credential after it has been created. - * - * @example - * ```ts - * import { WebAuthnP256 } from 'tempo.ts/viem' - * - * const credential = await WebAuthnP256.createCredential({ name: 'Example' }) - * // { - * // id: 'oZ48...', - * // publicKey: '0x...', - * // } - * ``` - * - * @param parameters WebAuthnP256 createCredential options. - * @returns WebAuthn credential. - */ -export async function createCredential( - parameters: createCredential.Parameters, -): Promise { - const { createFn, label, rpId, userId } = parameters - const credential = await WebAuthnP256.createCredential({ - ...parameters, - authenticatorSelection: { - ...parameters.authenticatorSelection, - requireResidentKey: true, - residentKey: 'required', - userVerification: 'required', - }, - createFn, - extensions: { - ...parameters.extensions, - credProps: true, - }, - rp: rpId - ? { - id: rpId, - name: rpId, - } - : undefined, - name: undefined as never, - user: { - displayName: label, - id: new Uint8Array(userId ?? Bytes.fromString(label)), - name: label, - }, - }) - return { - id: credential.id, - publicKey: PublicKey.toHex(credential.publicKey, { - includePrefix: false, - }), - raw: credential.raw, - } -} - -export declare namespace createCredential { - export type Parameters = Omit< - WebAuthnP256.createCredential.Options, - 'rp' | 'user' - > & { - /** - * Credential creation function. Useful for environments that do not support - * the WebAuthn API natively (i.e. React Native or testing environments). - * - * @default window.navigator.credentials.create - */ - createFn?: WebAuthnP256.createCredential.Options['createFn'] | undefined - /** Label. */ - label: string - /** Relying Party ID. */ - rpId?: string | undefined - /** User ID. */ - userId?: Bytes.Bytes | undefined - } - - export type ReturnValue = P256Credential -} - -/** - * Gets a WebAuthn credential (ie. a passkey), and optionally signs over a digest/hash. - * - * A `getPublicKey` function is required to fetch the public key paired with the credential - * from an external store. It is not possible to extract a public key from a credential after - * the credential has been created with `WebAuthnP256.createCredential`. - * - * @example - * ```ts - * import { WebAuthnP256 } from 'tempo.ts/viem' - * - * const credential = await WebAuthnP256.getCredential({ - * async getPublicKey(credential) { - * // Get public key from store - * return store.getPublicKey(credential.id) - * } - * }) - * ``` - * - * @param parameters WebAuthnP256 getCredential options. - * @returns WebAuthn credential. - */ -export async function getCredential( - parameters: getCredential.Parameters, -): Promise { - const { metadata, raw, signature } = await WebAuthnP256.sign({ - ...parameters, - challenge: parameters.hash ?? '0x', - }) - const publicKey = await parameters.getPublicKey(raw) - return { - id: raw.id, - metadata, - publicKey, - raw, - signature, - } -} - -export declare namespace getCredential { - export type Parameters = Omit & { - hash?: Hex.Hex | undefined - getPublicKey: ( - credential: WebAuthnP256.P256Credential['raw'], - ) => Promise - } - - export type ReturnValue = WebAuthnP256.sign.ReturnType & { - id: string - publicKey: Hex.Hex - } -} diff --git a/src/viem/WebCryptoP256.ts b/src/viem/WebCryptoP256.ts deleted file mode 100644 index 44d41a89..00000000 --- a/src/viem/WebCryptoP256.ts +++ /dev/null @@ -1 +0,0 @@ -export { createKeyPair } from 'ox/WebCryptoP256' diff --git a/src/viem/e2e.test.ts b/src/viem/e2e.test.ts deleted file mode 100644 index 98aa468d..00000000 --- a/src/viem/e2e.test.ts +++ /dev/null @@ -1,1602 +0,0 @@ -import * as Http from 'node:http' -import { createRequestListener } from '@remix-run/node-fetch-server' -import { RpcRequest, RpcResponse, WebCryptoP256 } from 'ox' -import { Account, Transaction } from 'tempo.ts/viem' -import { publicActions, walletActions } from 'viem' -import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts' -import { defaultPrepareTransactionRequestParameters } from 'viem/actions' -import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest' -import { rpcUrl } from '../../test/config.js' -import { - accounts, - client as client_, - fundAddress, - getClient, - http, -} from '../../test/viem/config.js' -import * as actions from './Actions/index.js' -import { tempoActions } from './index.js' -import { withFeePayer } from './Transport.js' - -const client = client_ - .extend(publicActions) - .extend(walletActions) - .extend(tempoActions()) - -describe('sendTransaction', () => { - describe('secp256k1', () => { - test('default', async () => { - const account = accounts[0] - - const hash = await client.sendTransaction({ - account, - data: '0xdeadbeef', - to: '0x0000000000000000000000000000000000000000', - }) - await client.waitForTransactionReceipt({ hash }) - - const { - blockHash, - blockNumber, - chainId, - from, - gas, - gasPrice, - hash: hash_, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ hash }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash_).toBe(hash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "calls": [ - { - "data": "0xdeadbeef", - "to": "0x0000000000000000000000000000000000000000", - "value": 0n, - }, - ], - "data": undefined, - "feePayerSignature": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - - test('with calls', async () => { - const account = accounts[0] - - const hash = await client.sendTransaction({ - account, - calls: [ - actions.token.create.call({ - admin: accounts[0].address, - currency: 'USD', - name: 'Test Token 3', - symbol: 'TEST3', - }), - ], - }) - await client.waitForTransactionReceipt({ hash }) - - const { - blockHash, - blockNumber, - calls, - chainId, - from, - gas, - gasPrice, - hash: hash_, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ hash }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(calls?.length).toBe(1) - expect(chainId).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash_).toBe(hash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "data": undefined, - "feePayerSignature": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - - test('with feePayer', async () => { - const account = privateKeyToAccount(generatePrivateKey()) - const feePayer = accounts[0] - - const hash = await client.sendTransaction({ - account, - feePayer, - to: '0x0000000000000000000000000000000000000000', - }) - await client.waitForTransactionReceipt({ hash }) - - const { - blockHash, - blockNumber, - chainId, - feePayerSignature, - from, - gas, - gasPrice, - hash: hash_, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ hash }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(feePayerSignature).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash_).toBe(hash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "calls": [ - { - "data": "0x", - "to": "0x0000000000000000000000000000000000000000", - "value": 0n, - }, - ], - "data": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - - test('with access key', async () => { - const account = accounts[0] - const accessKey = Account.fromP256(generatePrivateKey(), { - access: account, - }) - - const keyAuthorization = await account.signKeyAuthorization(accessKey) - await account.assignKeyAuthorization(keyAuthorization) - - { - const receipt = await client.sendTransactionSync({ - account: accessKey, - }) - expect(receipt).toBeDefined() - } - - // TODO: uncomment once unlimited spend supported - // { - // const receipt = await client.token.transferSync({ - // account: accessKey, - // amount: 100n, - // token: '0x20c0000000000000000000000000000000000001', - // to: '0x0000000000000000000000000000000000000001', - // }) - // expect(receipt).toBeDefined() - // } - - { - const receipt = await client.token.createSync({ - account: accessKey, - admin: accessKey.address, - currency: 'USD', - name: 'Test Token 4', - symbol: 'TEST4', - }) - expect(receipt).toBeDefined() - } - }) - - test('behavior: deploy contract', async () => { - const account = accounts[0] - const receipt = await client.sendTransactionSync({ - account, - data: '0x608060405234801561001057600080fd5b50610ee0806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033', - }) - expect(receipt.contractAddress).toBeDefined() - }) - - test('behavior: deploy contract + `feeToken` (tempo tx)', async () => { - const account = accounts[0] - const receipt = await client.sendTransactionSync({ - account, - feeToken: 1n, - data: '0x608060405234801561001057600080fd5b50610ee0806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033', - }) - expect(receipt.contractAddress).toBeDefined() - }) - }) - - describe('p256', () => { - test('default', async () => { - const account = Account.fromP256( - '0x6a3086fb3f2f95a3f36ef5387d18151ff51dc98a1e0eb987b159ba196beb0c99', - ) - - // fund account - await fundAddress(client, { address: account.address }) - - const receipt = await client.sendTransactionSync({ - account, - data: '0xdeadbeef', - to: '0x0000000000000000000000000000000000000000', - }) - - const { - blockHash, - blockNumber, - chainId, - from, - gas, - gasPrice, - hash, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ - hash: receipt.transactionHash, - }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash).toBe(receipt.transactionHash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "calls": [ - { - "data": "0xdeadbeef", - "to": "0x0000000000000000000000000000000000000000", - "value": 0n, - }, - ], - "data": undefined, - "feePayerSignature": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - - test('with calls', async () => { - const account = Account.fromP256( - '0x6a3086fb3f2f95a3f36ef5387d18151ff51dc98a1e0eb987b159ba196beb0c99', - ) - - // fund account - await fundAddress(client, { address: account.address }) - - const receipt = await client.sendTransactionSync({ - account, - calls: [ - actions.token.create.call({ - admin: account.address, - currency: 'USD', - name: 'Test Token 4', - symbol: 'TEST4', - }), - ], - // TODO: remove once `eth_estimateGas` supports passing key type. - gas: 100_000n, - }) - - const { - blockHash, - blockNumber, - calls, - chainId, - from, - gas, - gasPrice, - hash, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ - hash: receipt.transactionHash, - }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(calls?.length).toBe(1) - expect(chainId).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash).toBe(receipt.transactionHash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "data": undefined, - "feePayerSignature": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - - test('with feePayer', async () => { - const account = Account.fromP256( - // unfunded account with different key - '0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b', - ) - const feePayer = accounts[0] - - const hash = await client.sendTransaction({ - account, - feePayer, - to: '0x0000000000000000000000000000000000000000', - }) - await client.waitForTransactionReceipt({ hash }) - - const { - blockHash, - blockNumber, - chainId, - feePayerSignature, - from, - gas, - gasPrice, - hash: hash_, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ hash }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(feePayerSignature).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash_).toBe(hash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "calls": [ - { - "data": "0x", - "to": "0x0000000000000000000000000000000000000000", - "value": 0n, - }, - ], - "data": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - - test('with access key', async () => { - const account = accounts[0] - const accessKey = Account.fromP256(generatePrivateKey(), { - access: account, - }) - - const keyAuthorization = await account.signKeyAuthorization(accessKey) - await account.assignKeyAuthorization(keyAuthorization) - - { - const receipt = await client.sendTransactionSync({ - account: accessKey, - }) - expect(receipt).toBeDefined() - } - - { - const receipt = await client.sendTransactionSync({ - account: accessKey, - to: '0x0000000000000000000000000000000000000000', - }) - expect(receipt).toBeDefined() - } - }) - - test('with access key + fee payer', async () => { - const account = Account.fromP256( - // unfunded account with different key - '0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b', - ) - const accessKey = Account.fromP256(generatePrivateKey(), { - access: account, - }) - const feePayer = accounts[0] - - const keyAuthorization = await account.signKeyAuthorization(accessKey) - await account.assignKeyAuthorization(keyAuthorization) - - { - const receipt = await client.sendTransactionSync({ - account: accessKey, - feePayer, - to: '0x0000000000000000000000000000000000000000', - }) - expect(receipt).toBeDefined() - } - - { - const receipt = await client.sendTransactionSync({ - account: accessKey, - feePayer, - to: '0x0000000000000000000000000000000000000000', - }) - expect(receipt).toBeDefined() - } - }) - }) - - describe('webcrypto', () => { - test('default', async () => { - const keyPair = await WebCryptoP256.createKeyPair() - const account = Account.fromWebCryptoP256(keyPair) - - // fund account - await fundAddress(client, { address: account.address }) - - const receipt = await client.sendTransactionSync({ - account, - data: '0xdeadbeef', - to: '0x0000000000000000000000000000000000000000', - }) - - const { - blockHash, - blockNumber, - chainId, - from, - gasPrice, - hash, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ - hash: receipt.transactionHash, - }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(from).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash).toBe(receipt.transactionHash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "calls": [ - { - "data": "0xdeadbeef", - "to": "0x0000000000000000000000000000000000000000", - "value": 0n, - }, - ], - "data": undefined, - "feePayerSignature": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "gas": 29012n, - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - - test('with calls', async () => { - const keyPair = await WebCryptoP256.createKeyPair() - const account = Account.fromWebCryptoP256(keyPair) - - // fund account - await fundAddress(client, { address: account.address }) - - const receipt = await client.sendTransactionSync({ - account, - calls: [ - actions.token.create.call({ - admin: account.address, - currency: 'USD', - name: 'Test Token 5', - symbol: 'TEST5', - }), - ], - // TODO: remove once `eth_estimateGas` supports passing key type. - gas: 100_000n, - }) - - const { - blockHash, - blockNumber, - calls, - chainId, - from, - gas, - gasPrice, - hash, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - signature, - ...transaction - } = await client.getTransaction({ - hash: receipt.transactionHash, - }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(calls?.length).toBe(1) - expect(chainId).toBeDefined() - expect(from).toBeDefined() - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash).toBe(receipt.transactionHash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(signature).toBeDefined() - expect(transaction).toBeDefined() - }) - - test('with feePayer', async () => { - const keyPair = await WebCryptoP256.createKeyPair() - const account = Account.fromWebCryptoP256(keyPair) - const feePayer = accounts[0] - - const hash = await client.sendTransaction({ - account, - feePayer, - to: '0x0000000000000000000000000000000000000000', - }) - await client.waitForTransactionReceipt({ hash }) - - const { - blockHash, - blockNumber, - chainId, - from, - gasPrice, - hash: hash_, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - signature, - ...transaction - } = await client.getTransaction({ hash }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(from).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash_).toBe(hash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(signature).toBeDefined() - expect(transaction).toBeDefined() - }) - - test('with access key', async () => { - const keyPair = await WebCryptoP256.createKeyPair() - const account = Account.fromWebCryptoP256(keyPair) - const accessKey = Account.fromWebCryptoP256(keyPair, { - access: account, - }) - - // fund account - await fundAddress(client, { address: account.address }) - - const keyAuthorization = await account.signKeyAuthorization(accessKey) - await account.assignKeyAuthorization(keyAuthorization) - - { - const receipt = await client.sendTransactionSync({ - account: accessKey, - }) - expect(receipt).toBeDefined() - } - - { - const receipt = await client.sendTransactionSync({ - account: accessKey, - to: '0x0000000000000000000000000000000000000000', - }) - expect(receipt).toBeDefined() - } - }) - }) - - describe('webAuthn', () => { - test('default', async () => { - const account = Account.fromHeadlessWebAuthn( - '0x6a3086fb3f2f95a3f36ef5387d18151ff51dc98a1e0eb987b159ba196beb0c99', - { - rpId: 'localhost', - origin: 'http://localhost', - }, - ) - - // fund account - await fundAddress(client, { address: account.address }) - - const receipt = await client.sendTransactionSync({ - account, - data: '0xdeadbeef', - to: '0x0000000000000000000000000000000000000000', - }) - - const { - blockHash, - blockNumber, - chainId, - from, - gas, - gasPrice, - hash, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ - hash: receipt.transactionHash, - }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash).toBe(receipt.transactionHash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "calls": [ - { - "data": "0xdeadbeef", - "to": "0x0000000000000000000000000000000000000000", - "value": 0n, - }, - ], - "data": undefined, - "feePayerSignature": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - - test('with calls', async () => { - const account = Account.fromHeadlessWebAuthn( - '0x6a3086fb3f2f95a3f36ef5387d18151ff51dc98a1e0eb987b159ba196beb0c99', - { - rpId: 'localhost', - origin: 'http://localhost', - }, - ) - - // fund account - await fundAddress(client, { address: account.address }) - - const receipt = await client.sendTransactionSync({ - account, - calls: [ - actions.token.create.call({ - admin: account.address, - currency: 'USD', - name: 'Test Token 6', - symbol: 'TEST6', - }), - ], - // TODO: remove once `eth_estimateGas` supports passing key type. - gas: 100_000n, - }) - - const { - blockHash, - blockNumber, - calls, - chainId, - from, - gas, - gasPrice, - hash, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ - hash: receipt.transactionHash, - }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(calls?.length).toBe(1) - expect(chainId).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash).toBe(receipt.transactionHash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "data": undefined, - "feePayerSignature": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - - test('with feePayer', async () => { - const account = Account.fromHeadlessWebAuthn( - // unfunded account with different key - '0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b', - { - rpId: 'localhost', - origin: 'http://localhost', - }, - ) - const feePayer = accounts[0] - - const hash = await client.sendTransaction({ - account, - feePayer, - to: '0x0000000000000000000000000000000000000000', - }) - await client.waitForTransactionReceipt({ hash }) - - const { - blockHash, - blockNumber, - chainId, - feePayerSignature, - from, - gas, - gasPrice, - hash: hash_, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ hash }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(feePayerSignature).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash_).toBe(hash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "calls": [ - { - "data": "0x", - "to": "0x0000000000000000000000000000000000000000", - "value": 0n, - }, - ], - "data": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - - test('with access key', async () => { - const account = Account.fromHeadlessWebAuthn( - '0x6a3086fb3f2f95a3f36ef5387d18151ff51dc98a1e0eb987b159ba196beb0c99', - { - rpId: 'localhost', - origin: 'http://localhost', - }, - ) - const accessKey = Account.fromP256(generatePrivateKey(), { - access: account, - }) - - // fund account - await fundAddress(client, { address: account.address }) - - const keyAuthorization = await account.signKeyAuthorization(accessKey) - await account.assignKeyAuthorization(keyAuthorization) - - { - const receipt = await client.sendTransactionSync({ - account: accessKey, - }) - expect(receipt).toBeDefined() - } - - { - const receipt = await client.sendTransactionSync({ - account: accessKey, - to: '0x0000000000000000000000000000000000000000', - }) - expect(receipt).toBeDefined() - } - }) - }) - - test('behavior: 2d nonces', async () => { - const account = accounts[0] - - // fund account - await fundAddress(client, { address: account.address }) - - const receipts = await Promise.all([ - client.sendTransactionSync({ - account, - nonceKey: 'random', - to: '0x0000000000000000000000000000000000000000', - }), - client.sendTransactionSync({ - account, - nonceKey: 'random', - to: '0x0000000000000000000000000000000000000000', - }), - ]) - - expect(receipts[0].status).toBe('success') - expect(receipts[1].status).toBe('success') - expect(receipts[0].transactionHash).not.toBe(receipts[1].transactionHash) - }) - - test('behavior: 2d nonces (implicit)', async () => { - const account = accounts[0] - - // fund account - await fundAddress(client, { address: account.address }) - - const receipts = await Promise.all([ - client.sendTransactionSync({ - account, - to: '0x0000000000000000000000000000000000000000', - }), - client.sendTransactionSync({ - account, - to: '0x0000000000000000000000000000000000000000', - }), - client.sendTransactionSync({ - account, - to: '0x0000000000000000000000000000000000000000', - }), - ]) - - const transactions = await Promise.all([ - client.getTransaction({ hash: receipts[0].transactionHash }), - client.getTransaction({ hash: receipts[1].transactionHash }), - client.getTransaction({ hash: receipts[2].transactionHash }), - ]) - - expect(transactions[0].nonceKey).toBe(0n) - expect(transactions[1].nonceKey).toBeGreaterThan(0n) - expect(transactions[2].nonceKey).toBeGreaterThan(0n) - }) -}) - -describe('signTransaction', () => { - test('default', async () => { - const account = privateKeyToAccount( - // unfunded PK - '0xecc3fe55647412647e5c6b657c496803b08ef956f927b7a821da298cfbdd9666', - ) - const feePayer = accounts[0] - - const request = await client.prepareTransactionRequest({ - account, - data: '0xdeadbeef', - feePayer: true, - parameters: defaultPrepareTransactionRequestParameters, - to: '0xcafebabecafebabecafebabecafebabecafebabe', - }) - let transaction = await client.signTransaction(request as never) - - transaction = await client.signTransaction({ - ...Transaction.deserialize(transaction), - account, - feePayer, - } as never) - const hash = await client.sendRawTransaction({ - serializedTransaction: transaction, - }) - - await client.waitForTransactionReceipt({ hash }) - - const { - blockHash, - blockNumber, - chainId, - feePayerSignature, - from, - gasPrice, - hash: hash_, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction2 - } = await client.getTransaction({ hash }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(feePayerSignature).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gasPrice).toBeDefined() - expect(hash_).toBe(hash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction2).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "calls": [ - { - "data": "0xdeadbeef", - "to": "0xcafebabecafebabecafebabecafebabecafebabe", - "value": 0n, - }, - ], - "data": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "gas": 24002n, - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) -}) - -describe('relay', () => { - const client = getClient({ - transport: withFeePayer(http(), http('http://localhost:3050')), - }) - .extend(tempoActions()) - .extend(walletActions) - .extend(publicActions) - let server: Http.Server - - afterEach(async () => { - await fetch(`${rpcUrl}/restart`) - }) - - beforeAll(async () => { - server = Http.createServer( - createRequestListener(async (r) => { - const client = getClient({ - account: accounts[0], - }).extend(walletActions) - - const request = RpcRequest.from(await r.json()) - - // Validate method - if ( - (request as any).method !== 'eth_signRawTransaction' && - request.method !== 'eth_sendRawTransaction' && - request.method !== 'eth_sendRawTransactionSync' - ) - return Response.json( - RpcResponse.from( - { - error: new RpcResponse.InvalidParamsError({ - message: - 'service only supports `eth_signTransaction`, `eth_sendRawTransaction`, and `eth_sendRawTransactionSync`', - }), - }, - { request }, - ), - ) - - const serialized = request.params?.[0] as `0x76${string}` - if (!serialized.startsWith('0x76')) - return Response.json( - RpcResponse.from( - { - error: new RpcResponse.InvalidParamsError({ - message: 'service only supports `0x76` transactions', - }), - }, - { request }, - ), - ) - - const transaction = Transaction.deserialize(serialized) - const serializedTransaction = await client.signTransaction({ - ...transaction, - feePayer: client.account, - }) - - // Handle based on RPC method - if ((request as any).method === 'eth_signRawTransaction') { - // Policy: 'sign-only' - Return signed transaction without broadcasting - return Response.json( - RpcResponse.from({ result: serializedTransaction }, { request }), - ) - } - - // Policy: 'sign-and-broadcast' - Sign, broadcast, and return hash - const result = await client.request({ - method: request.method, - params: [serializedTransaction], - } as never) - - return Response.json(RpcResponse.from({ result }, { request })) - }), - ).listen(3050) - }) - - afterAll(() => { - server.close() - process.on('SIGINT', () => { - server.close() - process.exit(0) - }) - process.on('SIGTERM', () => { - server.close() - process.exit(0) - }) - }) - - describe('secp256k1', () => { - test('default', async () => { - const account = privateKeyToAccount( - // unfunded PK - '0xecc3fe55647412647e5c6b657c496803b08ef956f927b7a821da298cfbdd9666', - ) - - const { receipt } = await client.fee.setUserTokenSync({ - account, - feePayer: true, - token: 1n, - }) - - const userToken = await client.fee.getUserToken({ account }) - expect(userToken).toMatchInlineSnapshot(` - { - "address": "0x20C0000000000000000000000000000000000001", - "id": 1n, - } - `) - - const { - blockHash, - blockNumber, - chainId, - feePayerSignature, - from, - gas, - gasPrice, - hash, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ hash: receipt.transactionHash }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(feePayerSignature).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash).toBe(receipt.transactionHash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "calls": [ - { - "data": "0xe789744400000000000000000000000020c0000000000000000000000000000000000001", - "to": "0xfeec000000000000000000000000000000000000", - "value": 0n, - }, - ], - "data": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - - test('behavior: 2d nonces', async () => { - const account = privateKeyToAccount( - // unfunded PK - '0xecc3fe55647412647e5c6b657c496803b08ef956f927b7a821da298cfbdd9666', - ) - - const receipts = await Promise.all([ - client.sendTransactionSync({ - account, - feePayer: true, - to: '0x0000000000000000000000000000000000000000', - }), - client.sendTransactionSync({ - account, - feePayer: true, - to: '0x0000000000000000000000000000000000000001', - }), - client.sendTransactionSync({ - account, - feePayer: true, - to: '0x0000000000000000000000000000000000000002', - }), - ]) - - expect(receipts.every((receipt) => receipt.status === 'success')).toBe( - true, - ) - }) - - test('behavior: policy: sign-and-broadcast', async () => { - const client = getClient({ - transport: withFeePayer(http(), http('http://localhost:3050'), { - policy: 'sign-and-broadcast', - }), - }).extend(tempoActions()) - - // unfunded account that needs sponsorship - const account = privateKeyToAccount( - '0xecc3fe55647412647e5c6b657c496803b08ef956f927b7a821da298cfbdd9666', - ) - - const { receipt } = await client.fee.setUserTokenSync({ - account, - feePayer: true, - token: 1n, - }) - - expect(receipt.status).toBe('success') - }) - }) - - describe('p256', () => { - test('default', async () => { - const account = Account.fromP256( - '0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b', - ) - - const { receipt } = await client.fee.setUserTokenSync({ - account, - feePayer: true, - token: 1n, - }) - - const userToken = await client.fee.getUserToken({ account }) - expect(userToken).toMatchInlineSnapshot(` - { - "address": "0x20C0000000000000000000000000000000000001", - "id": 1n, - } - `) - - const { - blockHash, - blockNumber, - chainId, - feePayerSignature, - from, - gas, - gasPrice, - hash, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ hash: receipt.transactionHash }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(feePayerSignature).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash).toBe(receipt.transactionHash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "calls": [ - { - "data": "0xe789744400000000000000000000000020c0000000000000000000000000000000000001", - "to": "0xfeec000000000000000000000000000000000000", - "value": 0n, - }, - ], - "data": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - }) - - describe('webcrypto', () => { - test('default', async () => { - const keyPair = await WebCryptoP256.createKeyPair() - const account = Account.fromWebCryptoP256(keyPair) - - const { receipt } = await client.fee.setUserTokenSync({ - account, - feePayer: true, - token: 1n, - }) - - const userToken = await client.fee.getUserToken({ account }) - expect(userToken).toMatchInlineSnapshot(` - { - "address": "0x20C0000000000000000000000000000000000001", - "id": 1n, - } - `) - - const transaction = await client.getTransaction({ - hash: receipt.transactionHash, - }) - - expect(transaction).toBeDefined() - }) - }) - - describe('webAuthn', () => { - test('default', async () => { - const account = Account.fromHeadlessWebAuthn( - '0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b', - { - rpId: 'localhost', - origin: 'http://localhost', - }, - ) - - const { receipt } = await client.fee.setUserTokenSync({ - account, - feePayer: true, - token: 1n, - }) - - const userToken = await client.fee.getUserToken({ account }) - expect(userToken).toMatchInlineSnapshot(` - { - "address": "0x20C0000000000000000000000000000000000001", - "id": 1n, - } - `) - - const { - blockHash, - blockNumber, - chainId, - feePayerSignature, - from, - gas, - gasPrice, - hash, - keyAuthorization: __, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - nonceKey, - signature, - transactionIndex, - ...transaction - } = await client.getTransaction({ hash: receipt.transactionHash }) - - expect(blockHash).toBeDefined() - expect(blockNumber).toBeDefined() - expect(chainId).toBeDefined() - expect(feePayerSignature).toBeDefined() - expect(from).toBe(account.address.toLowerCase()) - expect(gas).toBeDefined() - expect(gasPrice).toBeDefined() - expect(hash).toBe(receipt.transactionHash) - expect(maxFeePerGas).toBeDefined() - expect(maxPriorityFeePerGas).toBeDefined() - expect(nonce).toBeDefined() - expect(nonceKey).toBeDefined() - expect(signature).toBeDefined() - expect(transactionIndex).toBeDefined() - expect(transaction).toMatchInlineSnapshot(` - { - "accessList": [], - "authorizationList": [], - "calls": [ - { - "data": "0xe789744400000000000000000000000020c0000000000000000000000000000000000001", - "to": "0xfeec000000000000000000000000000000000000", - "value": 0n, - }, - ], - "data": undefined, - "feeToken": "0x20c0000000000000000000000000000000000001", - "maxFeePerBlobGas": undefined, - "to": null, - "type": "tempo", - "typeHex": "0x76", - "v": undefined, - "validAfter": null, - "validBefore": null, - "value": 0n, - "yParity": undefined, - } - `) - }) - }) -}) diff --git a/src/viem/index.ts b/src/viem/index.ts deleted file mode 100644 index 2940d391..00000000 --- a/src/viem/index.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Export types required for inference. -export type { - /** @deprecated */ - KeyAuthorization as z_KeyAuthorization, - /** @deprecated */ - SignatureEnvelope as z_SignatureEnvelope, - /** @deprecated */ - TokenId as z_TokenId, - /** @deprecated */ - TxEnvelopeTempo as z_TxEnvelopeTempo, -} from 'ox/tempo' -export { Tick } from 'ox/tempo' -export * as Abis from './Abis.js' -export * as Account from './Account.js' -export * as Actions from './Actions/index.js' -export * as Addresses from './Addresses.js' -export * as Chain from './Chain.js' -export { - type Decorator as TempoActions, - decorator as tempoActions, -} from './Decorator.js' -export * as Formatters from './Formatters.js' -export * as P256 from './P256.js' -export * as Secp256k1 from './Secp256k1.js' -export * as TokenIds from './TokenIds.js' -export * as Transaction from './Transaction.js' -export * as Transport from './Transport.js' -export { withFeePayer } from './Transport.js' -export * as WebAuthnP256 from './WebAuthnP256.js' -export * as WebCryptoP256 from './WebCryptoP256.js' diff --git a/src/viem/internal/types.ts b/src/viem/internal/types.ts deleted file mode 100644 index d1934889..00000000 --- a/src/viem/internal/types.ts +++ /dev/null @@ -1,69 +0,0 @@ -import type { TokenId } from 'ox/tempo' -import type { - Account, - Address, - Chain, - ReadContractParameters as viem_ReadContractParameters, - WriteContractSyncParameters as viem_WriteContractSyncParameters, -} from 'viem' -import type { - IsUndefined, - MaybeRequired, - UnionPick, -} from '../../internal/types.js' -import type { TransactionRequestTempo } from '../Transaction.js' - -export type GetAccountParameter< - account extends Account | undefined = Account | undefined, - accountOverride extends Account | Address | undefined = Account | Address, - required extends boolean = true, - nullish extends boolean = false, -> = MaybeRequired< - { - account?: - | accountOverride - | Account - | Address - | (nullish extends true ? null : never) - | undefined - }, - IsUndefined extends true - ? required extends true - ? true - : false - : false -> - -export type GetFeeTokenParameter< - chain extends Chain | undefined = Chain | undefined, -> = chain extends { feeToken: infer feeToken } - ? IsUndefined extends true - ? { feeToken: TokenId.TokenIdOrAddress | null } - : { feeToken?: TokenId.TokenIdOrAddress | null | undefined } - : { feeToken: TokenId.TokenIdOrAddress | null } - -export type ReadParameters = Pick< - viem_ReadContractParameters, - 'account' | 'blockNumber' | 'blockOverrides' | 'blockTag' | 'stateOverride' -> - -export type TokenIdOrAddress = bigint | Address - -export type WriteParameters< - chain extends Chain | undefined = Chain | undefined, - account extends Account | undefined = Account | undefined, -> = UnionPick< - viem_WriteContractSyncParameters, - | 'account' - | 'chain' - | 'gas' - | 'maxFeePerGas' - | 'maxPriorityFeePerGas' - | 'nonce' - | 'throwOnReceiptRevert' -> & - GetFeeTokenParameter & - UnionPick< - TransactionRequestTempo, - 'feePayer' | 'nonceKey' | 'validAfter' | 'validBefore' - > diff --git a/src/viem/internal/utils.ts b/src/viem/internal/utils.ts deleted file mode 100644 index 0457fa0c..00000000 --- a/src/viem/internal/utils.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { - type Abi, - type AbiStateMutability, - type Address, - type ContractFunctionName, - type ContractFunctionParameters, - type ExtractAbiItem, - encodeFunctionData, - type Hex, -} from 'viem' - -export function defineCall< - const abi extends Abi, - const functionName extends ContractFunctionName, - call extends ContractFunctionParameters< - abi, - AbiStateMutability, - functionName - >, ->( - call: - | call - | ContractFunctionParameters, -): ContractFunctionParameters< - [ExtractAbiItem], - AbiStateMutability, - functionName -> & { - data: Hex - to: Address -} { - return { - ...(call as any), - data: encodeFunctionData(call as never), - to: call.address, - } as const -} - -/** - * Normalizes a value into a structured-clone compatible format. - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/structuredClone - */ -export function normalizeValue(value: type): type { - if (Array.isArray(value)) return value.map(normalizeValue) as never - if (typeof value === 'function') return undefined as never - if (typeof value !== 'object' || value === null) return value - if (Object.getPrototypeOf(value) !== Object.prototype) - try { - return structuredClone(value) - } catch { - return undefined as never - } - - const normalized: Record = {} - for (const [k, v] of Object.entries(value)) normalized[k] = normalizeValue(v) - return normalized as never -} diff --git a/src/wagmi/Actions/amm.ts b/src/wagmi/Actions/amm.ts index 957ae245..19ae80db 100644 --- a/src/wagmi/Actions/amm.ts +++ b/src/wagmi/Actions/amm.ts @@ -2,8 +2,8 @@ import type * as Query from '@tanstack/query-core' import { type Config, getConnectorClient } from '@wagmi/core' import type { ChainIdParameter, ConnectorParameter } from '@wagmi/core/internal' import type { Account } from 'viem' +import { Actions } from 'viem/tempo' import type { RequiredBy, UnionOmit } from '../../internal/types.js' -import * as viem_Actions from '../../viem/Actions/amm.js' /** * Gets the reserves for a liquidity pool. @@ -11,11 +11,11 @@ import * as viem_Actions from '../../viem/Actions/amm.js' * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -37,14 +37,14 @@ export function getPool( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getPool(client, rest) + return Actions.amm.getPool(client, rest) } export namespace getPool { export type Parameters = ChainIdParameter & - viem_Actions.getPool.Parameters + Actions.amm.getPool.Parameters - export type ReturnValue = viem_Actions.getPool.ReturnValue + export type ReturnValue = Actions.amm.getPool.ReturnValue export function queryKey( parameters: Parameters, @@ -102,11 +102,11 @@ export namespace getPool { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -133,14 +133,14 @@ export function getLiquidityBalance( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getLiquidityBalance(client, rest) + return Actions.amm.getLiquidityBalance(client, rest) } export namespace getLiquidityBalance { export type Parameters = ChainIdParameter & - viem_Actions.getLiquidityBalance.Parameters + Actions.amm.getLiquidityBalance.Parameters - export type ReturnValue = viem_Actions.getLiquidityBalance.ReturnValue + export type ReturnValue = Actions.amm.getLiquidityBalance.ReturnValue export function queryKey( parameters: Parameters, @@ -198,11 +198,11 @@ export namespace getLiquidityBalance { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -223,7 +223,7 @@ export namespace getLiquidityBalance { export async function rebalanceSwap( config: config, parameters: rebalanceSwap.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -233,18 +233,18 @@ export async function rebalanceSwap( connector, }) - return viem_Actions.rebalanceSwap(client, parameters as never) + return Actions.amm.rebalanceSwap(client, parameters as never) } export declare namespace rebalanceSwap { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.rebalanceSwap.Parameters, + Actions.amm.rebalanceSwap.Parameters, 'chain' > - export type ReturnValue = viem_Actions.rebalanceSwap.ReturnValue + export type ReturnValue = Actions.amm.rebalanceSwap.ReturnValue } /** @@ -253,11 +253,11 @@ export declare namespace rebalanceSwap { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -278,7 +278,7 @@ export declare namespace rebalanceSwap { export async function rebalanceSwapSync( config: config, parameters: rebalanceSwapSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -288,21 +288,21 @@ export async function rebalanceSwapSync( connector, }) - return viem_Actions.rebalanceSwapSync(client, parameters as never) + return Actions.amm.rebalanceSwapSync(client, parameters as never) } export declare namespace rebalanceSwapSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.rebalanceSwapSync.Parameters< + Actions.amm.rebalanceSwapSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.rebalanceSwapSync.ReturnValue + export type ReturnValue = Actions.amm.rebalanceSwapSync.ReturnValue } /** @@ -311,11 +311,11 @@ export declare namespace rebalanceSwapSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -336,7 +336,7 @@ export declare namespace rebalanceSwapSync { export async function mint( config: config, parameters: mint.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -346,18 +346,18 @@ export async function mint( connector, }) - return viem_Actions.mint(client, parameters as never) + return Actions.amm.mint(client, parameters as never) } export declare namespace mint { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.mint.Parameters, + Actions.amm.mint.Parameters, 'chain' > - export type ReturnValue = viem_Actions.mint.ReturnValue + export type ReturnValue = Actions.amm.mint.ReturnValue } /** @@ -366,11 +366,11 @@ export declare namespace mint { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -391,7 +391,7 @@ export declare namespace mint { export async function mintSync( config: config, parameters: mintSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -401,18 +401,18 @@ export async function mintSync( connector, }) - return viem_Actions.mintSync(client, parameters as never) + return Actions.amm.mintSync(client, parameters as never) } export declare namespace mintSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.mintSync.Parameters, + Actions.amm.mintSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.mintSync.ReturnValue + export type ReturnValue = Actions.amm.mintSync.ReturnValue } /** @@ -421,11 +421,11 @@ export declare namespace mintSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -446,7 +446,7 @@ export declare namespace mintSync { export async function burn( config: config, parameters: burn.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -456,18 +456,18 @@ export async function burn( connector, }) - return viem_Actions.burn(client, parameters as never) + return Actions.amm.burn(client, parameters as never) } export declare namespace burn { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.burn.Parameters, + Actions.amm.burn.Parameters, 'chain' > - export type ReturnValue = viem_Actions.burn.ReturnValue + export type ReturnValue = Actions.amm.burn.ReturnValue } /** @@ -476,11 +476,11 @@ export declare namespace burn { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -501,7 +501,7 @@ export declare namespace burn { export async function burnSync( config: config, parameters: burnSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -511,18 +511,18 @@ export async function burnSync( connector, }) - return viem_Actions.burnSync(client, parameters as never) + return Actions.amm.burnSync(client, parameters as never) } export declare namespace burnSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.burnSync.Parameters, + Actions.amm.burnSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.burnSync.ReturnValue + export type ReturnValue = Actions.amm.burnSync.ReturnValue } /** @@ -531,11 +531,11 @@ export declare namespace burnSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -558,12 +558,12 @@ export function watchRebalanceSwap( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchRebalanceSwap(client, rest) + return Actions.amm.watchRebalanceSwap(client, rest) } export declare namespace watchRebalanceSwap { export type Parameters = ChainIdParameter & - viem_Actions.watchRebalanceSwap.Parameters + Actions.amm.watchRebalanceSwap.Parameters } /** @@ -572,11 +572,11 @@ export declare namespace watchRebalanceSwap { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -599,12 +599,12 @@ export function watchFeeSwap( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchFeeSwap(client, rest) + return Actions.amm.watchFeeSwap(client, rest) } export declare namespace watchFeeSwap { export type Parameters = ChainIdParameter & - viem_Actions.watchFeeSwap.Parameters + Actions.amm.watchFeeSwap.Parameters } /** @@ -613,11 +613,11 @@ export declare namespace watchFeeSwap { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -640,12 +640,12 @@ export function watchMint( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchMint(client, rest) + return Actions.amm.watchMint(client, rest) } export declare namespace watchMint { export type Parameters = ChainIdParameter & - viem_Actions.watchMint.Parameters + Actions.amm.watchMint.Parameters } /** @@ -654,11 +654,11 @@ export declare namespace watchMint { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -681,10 +681,10 @@ export function watchBurn( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchBurn(client, rest) + return Actions.amm.watchBurn(client, rest) } export declare namespace watchBurn { export type Parameters = ChainIdParameter & - viem_Actions.watchBurn.Parameters + Actions.amm.watchBurn.Parameters } diff --git a/src/wagmi/Actions/dex.test.ts b/src/wagmi/Actions/dex.test.ts index 87addae0..4a26b03e 100644 --- a/src/wagmi/Actions/dex.test.ts +++ b/src/wagmi/Actions/dex.test.ts @@ -1,7 +1,7 @@ import { connect } from '@wagmi/core' -import { Tick } from 'tempo.ts/viem' import { Actions } from 'tempo.ts/wagmi' import { isAddress, parseUnits } from 'viem' +import { Tick } from 'viem/tempo' import { beforeAll, describe, expect, test } from 'vitest' import { addresses } from '../../../test/config.js' import { accounts } from '../../../test/viem/config.js' diff --git a/src/wagmi/Actions/dex.ts b/src/wagmi/Actions/dex.ts index e6b4892d..16c9308c 100644 --- a/src/wagmi/Actions/dex.ts +++ b/src/wagmi/Actions/dex.ts @@ -2,8 +2,8 @@ import type * as Query from '@tanstack/query-core' import { type Config, getConnectorClient } from '@wagmi/core' import type { ChainIdParameter, ConnectorParameter } from '@wagmi/core/internal' import type { Account } from 'viem' +import { Actions } from 'viem/tempo' import type { PartialBy, RequiredBy, UnionOmit } from '../../internal/types.js' -import * as viem_Actions from '../../viem/Actions/dex.js' /** * Buys a specific amount of tokens. @@ -11,11 +11,11 @@ import * as viem_Actions from '../../viem/Actions/dex.js' * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -36,7 +36,7 @@ import * as viem_Actions from '../../viem/Actions/dex.js' export async function buy( config: config, parameters: buy.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -46,20 +46,20 @@ export async function buy( connector, }) - return viem_Actions.buy(client, parameters as never) + return Actions.dex.buy(client, parameters as never) } export declare namespace buy { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.buy.Parameters, + Actions.dex.buy.Parameters, 'chain' > - export type ReturnValue = viem_Actions.buy.ReturnValue + export type ReturnValue = Actions.dex.buy.ReturnValue - export type ErrorType = viem_Actions.buy.ErrorType + export type ErrorType = Actions.dex.buy.ErrorType } /** @@ -71,11 +71,11 @@ export declare namespace buy { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -96,7 +96,7 @@ export declare namespace buy { export async function buySync( config: config, parameters: buySync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -106,20 +106,20 @@ export async function buySync( connector, }) - return viem_Actions.buySync(client, parameters as never) + return Actions.dex.buySync(client, parameters as never) } export declare namespace buySync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.buySync.Parameters, + Actions.dex.buySync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.buySync.ReturnValue + export type ReturnValue = Actions.dex.buySync.ReturnValue - export type ErrorType = viem_Actions.buySync.ErrorType + export type ErrorType = Actions.dex.buySync.ErrorType } /** @@ -128,11 +128,11 @@ export declare namespace buySync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -150,7 +150,7 @@ export declare namespace buySync { export async function cancel( config: config, parameters: cancel.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -160,20 +160,20 @@ export async function cancel( connector, }) - return viem_Actions.cancel(client, parameters as never) + return Actions.dex.cancel(client, parameters as never) } export declare namespace cancel { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.cancel.Parameters, + Actions.dex.cancel.Parameters, 'chain' > - export type ReturnValue = viem_Actions.cancel.ReturnValue + export type ReturnValue = Actions.dex.cancel.ReturnValue - export type ErrorType = viem_Actions.cancel.ErrorType + export type ErrorType = Actions.dex.cancel.ErrorType } /** @@ -185,11 +185,11 @@ export declare namespace cancel { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -207,7 +207,7 @@ export declare namespace cancel { export async function cancelSync( config: config, parameters: cancelSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -217,20 +217,20 @@ export async function cancelSync( connector, }) - return viem_Actions.cancelSync(client, parameters as never) + return Actions.dex.cancelSync(client, parameters as never) } export declare namespace cancelSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.cancelSync.Parameters, + Actions.dex.cancelSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.cancelSync.ReturnValue + export type ReturnValue = Actions.dex.cancelSync.ReturnValue - export type ErrorType = viem_Actions.cancelSync.ErrorType + export type ErrorType = Actions.dex.cancelSync.ErrorType } /** @@ -239,11 +239,11 @@ export declare namespace cancelSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -261,7 +261,7 @@ export declare namespace cancelSync { export async function createPair( config: config, parameters: createPair.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -271,20 +271,20 @@ export async function createPair( connector, }) - return viem_Actions.createPair(client, parameters as never) + return Actions.dex.createPair(client, parameters as never) } export declare namespace createPair { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.createPair.Parameters, + Actions.dex.createPair.Parameters, 'chain' > - export type ReturnValue = viem_Actions.createPair.ReturnValue + export type ReturnValue = Actions.dex.createPair.ReturnValue - export type ErrorType = viem_Actions.createPair.ErrorType + export type ErrorType = Actions.dex.createPair.ErrorType } /** @@ -296,11 +296,11 @@ export declare namespace createPair { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -318,7 +318,7 @@ export declare namespace createPair { export async function createPairSync( config: config, parameters: createPairSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -328,20 +328,20 @@ export async function createPairSync( connector, }) - return viem_Actions.createPairSync(client, parameters as never) + return Actions.dex.createPairSync(client, parameters as never) } export declare namespace createPairSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.createPairSync.Parameters, + Actions.dex.createPairSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.createPairSync.ReturnValue + export type ReturnValue = Actions.dex.createPairSync.ReturnValue - export type ErrorType = viem_Actions.createPairSync.ErrorType + export type ErrorType = Actions.dex.createPairSync.ErrorType } /** @@ -350,11 +350,11 @@ export declare namespace createPairSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -376,14 +376,14 @@ export function getBalance( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getBalance(client, rest) + return Actions.dex.getBalance(client, rest) } export namespace getBalance { export type Parameters = ChainIdParameter & - viem_Actions.getBalance.Parameters + Actions.dex.getBalance.Parameters - export type ReturnValue = viem_Actions.getBalance.ReturnValue + export type ReturnValue = Actions.dex.getBalance.ReturnValue export function queryKey( parameters: PartialBy, 'account'>, @@ -442,11 +442,11 @@ export namespace getBalance { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -469,14 +469,14 @@ export function getBuyQuote( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getBuyQuote(client, rest) + return Actions.dex.getBuyQuote(client, rest) } export namespace getBuyQuote { export type Parameters = ChainIdParameter & - viem_Actions.getBuyQuote.Parameters + Actions.dex.getBuyQuote.Parameters - export type ReturnValue = viem_Actions.getBuyQuote.ReturnValue + export type ReturnValue = Actions.dex.getBuyQuote.ReturnValue export function queryKey( parameters: Parameters, @@ -534,11 +534,11 @@ export namespace getBuyQuote { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -559,14 +559,14 @@ export function getOrder( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getOrder(client, rest) + return Actions.dex.getOrder(client, rest) } export namespace getOrder { export type Parameters = ChainIdParameter & - viem_Actions.getOrder.Parameters + Actions.dex.getOrder.Parameters - export type ReturnValue = viem_Actions.getOrder.ReturnValue + export type ReturnValue = Actions.dex.getOrder.ReturnValue export function queryKey( parameters: Parameters, @@ -624,11 +624,11 @@ export namespace getOrder { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -650,14 +650,14 @@ export function getOrderbook( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getOrderbook(client, rest) + return Actions.dex.getOrderbook(client, rest) } export namespace getOrderbook { export type Parameters = ChainIdParameter & - viem_Actions.getOrderbook.Parameters + Actions.dex.getOrderbook.Parameters - export type ReturnValue = viem_Actions.getOrderbook.ReturnValue + export type ReturnValue = Actions.dex.getOrderbook.ReturnValue export function queryKey( parameters: Parameters, @@ -715,11 +715,11 @@ export namespace getOrderbook { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions, Tick } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -742,14 +742,14 @@ export function getTickLevel( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getTickLevel(client, rest) + return Actions.dex.getTickLevel(client, rest) } export namespace getTickLevel { export type Parameters = ChainIdParameter & - viem_Actions.getTickLevel.Parameters + Actions.dex.getTickLevel.Parameters - export type ReturnValue = viem_Actions.getTickLevel.ReturnValue + export type ReturnValue = Actions.dex.getTickLevel.ReturnValue export function queryKey( parameters: Parameters, @@ -807,11 +807,11 @@ export namespace getTickLevel { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -834,14 +834,14 @@ export function getSellQuote( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getSellQuote(client, rest) + return Actions.dex.getSellQuote(client, rest) } export namespace getSellQuote { export type Parameters = ChainIdParameter & - viem_Actions.getSellQuote.Parameters + Actions.dex.getSellQuote.Parameters - export type ReturnValue = viem_Actions.getSellQuote.ReturnValue + export type ReturnValue = Actions.dex.getSellQuote.ReturnValue export function queryKey( parameters: Parameters, @@ -899,11 +899,11 @@ export namespace getSellQuote { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -924,7 +924,7 @@ export namespace getSellQuote { export async function place( config: config, parameters: place.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -934,20 +934,20 @@ export async function place( connector, }) - return viem_Actions.place(client, parameters as never) + return Actions.dex.place(client, parameters as never) } export declare namespace place { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.place.Parameters, + Actions.dex.place.Parameters, 'chain' > - export type ReturnValue = viem_Actions.place.ReturnValue + export type ReturnValue = Actions.dex.place.ReturnValue - export type ErrorType = viem_Actions.place.ErrorType + export type ErrorType = Actions.dex.place.ErrorType } /** @@ -956,11 +956,11 @@ export declare namespace place { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -982,7 +982,7 @@ export declare namespace place { export async function placeFlip( config: config, parameters: placeFlip.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -992,20 +992,20 @@ export async function placeFlip( connector, }) - return viem_Actions.placeFlip(client, parameters as never) + return Actions.dex.placeFlip(client, parameters as never) } export declare namespace placeFlip { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.placeFlip.Parameters, + Actions.dex.placeFlip.Parameters, 'chain' > - export type ReturnValue = viem_Actions.placeFlip.ReturnValue + export type ReturnValue = Actions.dex.placeFlip.ReturnValue - export type ErrorType = viem_Actions.placeFlip.ErrorType + export type ErrorType = Actions.dex.placeFlip.ErrorType } /** @@ -1017,11 +1017,11 @@ export declare namespace placeFlip { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1043,7 +1043,7 @@ export declare namespace placeFlip { export async function placeFlipSync( config: config, parameters: placeFlipSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1053,20 +1053,20 @@ export async function placeFlipSync( connector, }) - return viem_Actions.placeFlipSync(client, parameters as never) + return Actions.dex.placeFlipSync(client, parameters as never) } export declare namespace placeFlipSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.placeFlipSync.Parameters, + Actions.dex.placeFlipSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.placeFlipSync.ReturnValue + export type ReturnValue = Actions.dex.placeFlipSync.ReturnValue - export type ErrorType = viem_Actions.placeFlipSync.ErrorType + export type ErrorType = Actions.dex.placeFlipSync.ErrorType } /** @@ -1078,11 +1078,11 @@ export declare namespace placeFlipSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1103,7 +1103,7 @@ export declare namespace placeFlipSync { export async function placeSync( config: config, parameters: placeSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1113,20 +1113,20 @@ export async function placeSync( connector, }) - return viem_Actions.placeSync(client, parameters as never) + return Actions.dex.placeSync(client, parameters as never) } export declare namespace placeSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.placeSync.Parameters, + Actions.dex.placeSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.placeSync.ReturnValue + export type ReturnValue = Actions.dex.placeSync.ReturnValue - export type ErrorType = viem_Actions.placeSync.ErrorType + export type ErrorType = Actions.dex.placeSync.ErrorType } /** @@ -1135,11 +1135,11 @@ export declare namespace placeSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1160,7 +1160,7 @@ export declare namespace placeSync { export async function sell( config: config, parameters: sell.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1170,20 +1170,20 @@ export async function sell( connector, }) - return viem_Actions.sell(client, parameters as never) + return Actions.dex.sell(client, parameters as never) } export declare namespace sell { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.sell.Parameters, + Actions.dex.sell.Parameters, 'chain' > - export type ReturnValue = viem_Actions.sell.ReturnValue + export type ReturnValue = Actions.dex.sell.ReturnValue - export type ErrorType = viem_Actions.sell.ErrorType + export type ErrorType = Actions.dex.sell.ErrorType } /** @@ -1195,11 +1195,11 @@ export declare namespace sell { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1220,7 +1220,7 @@ export declare namespace sell { export async function sellSync( config: config, parameters: sellSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1230,20 +1230,20 @@ export async function sellSync( connector, }) - return viem_Actions.sellSync(client, parameters as never) + return Actions.dex.sellSync(client, parameters as never) } export declare namespace sellSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.sellSync.Parameters, + Actions.dex.sellSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.sellSync.ReturnValue + export type ReturnValue = Actions.dex.sellSync.ReturnValue - export type ErrorType = viem_Actions.sellSync.ErrorType + export type ErrorType = Actions.dex.sellSync.ErrorType } /** @@ -1252,11 +1252,11 @@ export declare namespace sellSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1279,16 +1279,16 @@ export function watchFlipOrderPlaced( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchFlipOrderPlaced(client, rest) + return Actions.dex.watchFlipOrderPlaced(client, rest) } export declare namespace watchFlipOrderPlaced { export type Parameters = ChainIdParameter & - viem_Actions.watchFlipOrderPlaced.Parameters + Actions.dex.watchFlipOrderPlaced.Parameters - export type Args = viem_Actions.watchFlipOrderPlaced.Args + export type Args = Actions.dex.watchFlipOrderPlaced.Args - export type Log = viem_Actions.watchFlipOrderPlaced.Log + export type Log = Actions.dex.watchFlipOrderPlaced.Log } /** @@ -1297,11 +1297,11 @@ export declare namespace watchFlipOrderPlaced { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1324,16 +1324,16 @@ export function watchOrderCancelled( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchOrderCancelled(client, rest) + return Actions.dex.watchOrderCancelled(client, rest) } export declare namespace watchOrderCancelled { export type Parameters = ChainIdParameter & - viem_Actions.watchOrderCancelled.Parameters + Actions.dex.watchOrderCancelled.Parameters - export type Args = viem_Actions.watchOrderCancelled.Args + export type Args = Actions.dex.watchOrderCancelled.Args - export type Log = viem_Actions.watchOrderCancelled.Log + export type Log = Actions.dex.watchOrderCancelled.Log } /** @@ -1342,11 +1342,11 @@ export declare namespace watchOrderCancelled { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1369,16 +1369,16 @@ export function watchOrderFilled( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchOrderFilled(client, rest) + return Actions.dex.watchOrderFilled(client, rest) } export declare namespace watchOrderFilled { export type Parameters = ChainIdParameter & - viem_Actions.watchOrderFilled.Parameters + Actions.dex.watchOrderFilled.Parameters - export type Args = viem_Actions.watchOrderFilled.Args + export type Args = Actions.dex.watchOrderFilled.Args - export type Log = viem_Actions.watchOrderFilled.Log + export type Log = Actions.dex.watchOrderFilled.Log } /** @@ -1387,11 +1387,11 @@ export declare namespace watchOrderFilled { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1414,16 +1414,16 @@ export function watchOrderPlaced( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchOrderPlaced(client, rest) + return Actions.dex.watchOrderPlaced(client, rest) } export declare namespace watchOrderPlaced { export type Parameters = ChainIdParameter & - viem_Actions.watchOrderPlaced.Parameters + Actions.dex.watchOrderPlaced.Parameters - export type Args = viem_Actions.watchOrderPlaced.Args + export type Args = Actions.dex.watchOrderPlaced.Args - export type Log = viem_Actions.watchOrderPlaced.Log + export type Log = Actions.dex.watchOrderPlaced.Log } /** @@ -1432,11 +1432,11 @@ export declare namespace watchOrderPlaced { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1455,7 +1455,7 @@ export declare namespace watchOrderPlaced { export async function withdraw( config: config, parameters: withdraw.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1465,20 +1465,20 @@ export async function withdraw( connector, }) - return viem_Actions.withdraw(client, parameters as never) + return Actions.dex.withdraw(client, parameters as never) } export declare namespace withdraw { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.withdraw.Parameters, + Actions.dex.withdraw.Parameters, 'chain' > - export type ReturnValue = viem_Actions.withdraw.ReturnValue + export type ReturnValue = Actions.dex.withdraw.ReturnValue - export type ErrorType = viem_Actions.withdraw.ErrorType + export type ErrorType = Actions.dex.withdraw.ErrorType } /** @@ -1490,11 +1490,11 @@ export declare namespace withdraw { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1513,7 +1513,7 @@ export declare namespace withdraw { export async function withdrawSync( config: config, parameters: withdrawSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1523,18 +1523,18 @@ export async function withdrawSync( connector, }) - return viem_Actions.withdrawSync(client, parameters as never) + return Actions.dex.withdrawSync(client, parameters as never) } export declare namespace withdrawSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.withdrawSync.Parameters, + Actions.dex.withdrawSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.withdrawSync.ReturnValue + export type ReturnValue = Actions.dex.withdrawSync.ReturnValue - export type ErrorType = viem_Actions.withdrawSync.ErrorType + export type ErrorType = Actions.dex.withdrawSync.ErrorType } diff --git a/src/wagmi/Actions/faucet.ts b/src/wagmi/Actions/faucet.ts index 27903278..5c0c9f63 100644 --- a/src/wagmi/Actions/faucet.ts +++ b/src/wagmi/Actions/faucet.ts @@ -1,6 +1,6 @@ import type { Config } from '@wagmi/core' import type { ChainIdParameter, UnionCompute } from '@wagmi/core/internal' -import * as viem_Actions from '../../viem/Actions/faucet.js' +import { Actions } from 'viem/tempo' /** * Funds an account with an initial amount of set token(s) @@ -9,11 +9,11 @@ import * as viem_Actions from '../../viem/Actions/faucet.js' * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -34,15 +34,15 @@ export async function fund( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.fund(client, rest) + return Actions.faucet.fund(client, rest) } export declare namespace fund { export type Parameters = UnionCompute< - ChainIdParameter & viem_Actions.fund.Parameters + ChainIdParameter & Actions.faucet.fund.Parameters > - export type ReturnValue = viem_Actions.fund.ReturnValue + export type ReturnValue = Actions.faucet.fund.ReturnValue } /** @@ -52,11 +52,11 @@ export declare namespace fund { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -77,13 +77,13 @@ export async function fundSync( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.fundSync(client, rest) + return Actions.faucet.fundSync(client, rest) } export declare namespace fundSync { export type Parameters = UnionCompute< - ChainIdParameter & viem_Actions.fundSync.Parameters + ChainIdParameter & Actions.faucet.fundSync.Parameters > - export type ReturnValue = viem_Actions.fundSync.ReturnValue + export type ReturnValue = Actions.faucet.fundSync.ReturnValue } diff --git a/src/wagmi/Actions/fee.ts b/src/wagmi/Actions/fee.ts index c3b64809..b2faffe7 100644 --- a/src/wagmi/Actions/fee.ts +++ b/src/wagmi/Actions/fee.ts @@ -2,8 +2,8 @@ import type * as Query from '@tanstack/query-core' import { type Config, getConnectorClient } from '@wagmi/core' import type { ChainIdParameter, ConnectorParameter } from '@wagmi/core/internal' import type { Account } from 'viem' +import { Actions } from 'viem/tempo' import type { PartialBy, RequiredBy, UnionOmit } from '../../internal/types.js' -import * as viem_Actions from '../../viem/Actions/fee.js' /** * Gets the user's default fee token. @@ -11,11 +11,11 @@ import * as viem_Actions from '../../viem/Actions/fee.js' * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -36,14 +36,14 @@ export function getUserToken( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getUserToken(client, rest) + return Actions.fee.getUserToken(client, rest) } export namespace getUserToken { export type Parameters = ChainIdParameter & - viem_Actions.getUserToken.Parameters + Actions.fee.getUserToken.Parameters - export type ReturnValue = viem_Actions.getUserToken.ReturnValue + export type ReturnValue = Actions.fee.getUserToken.ReturnValue export function queryKey( parameters: PartialBy, 'account'>, @@ -102,11 +102,11 @@ export namespace getUserToken { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -124,7 +124,7 @@ export namespace getUserToken { export async function setUserToken( config: config, parameters: setUserToken.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -134,20 +134,20 @@ export async function setUserToken( connector, }) - return viem_Actions.setUserToken(client, parameters as never) + return Actions.fee.setUserToken(client, parameters as never) } export declare namespace setUserToken { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.setUserToken.Parameters, + Actions.fee.setUserToken.Parameters, 'chain' > - export type ReturnValue = viem_Actions.setUserToken.ReturnValue + export type ReturnValue = Actions.fee.setUserToken.ReturnValue - export type ErrorType = viem_Actions.setUserToken.ErrorType + export type ErrorType = Actions.fee.setUserToken.ErrorType } /** @@ -159,11 +159,11 @@ export declare namespace setUserToken { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -181,7 +181,7 @@ export declare namespace setUserToken { export async function setUserTokenSync( config: config, parameters: setUserTokenSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -191,21 +191,21 @@ export async function setUserTokenSync( connector, }) - return viem_Actions.setUserTokenSync(client, parameters as never) + return Actions.fee.setUserTokenSync(client, parameters as never) } export declare namespace setUserTokenSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.setUserTokenSync.Parameters< + Actions.fee.setUserTokenSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.setUserTokenSync.ReturnValue + export type ReturnValue = Actions.fee.setUserTokenSync.ReturnValue - export type ErrorType = viem_Actions.setUserTokenSync.ErrorType + export type ErrorType = Actions.fee.setUserTokenSync.ErrorType } diff --git a/src/wagmi/Actions/nonce.test.ts b/src/wagmi/Actions/nonce.test.ts index 74c60c4d..c19b4c3f 100644 --- a/src/wagmi/Actions/nonce.test.ts +++ b/src/wagmi/Actions/nonce.test.ts @@ -6,7 +6,7 @@ import { config, queryClient } from '../../../test/wagmi/config.js' import * as nonce from './nonce.js' import * as token from './token.js' -const { getNonceKeyCount, getNonce } = nonce +const { getNonce } = nonce const account = accounts[0] const account2 = accounts[1] @@ -36,24 +36,6 @@ describe('getNonce', () => { }) }) -describe('getNonceKeyCount', () => { - test('default', async () => { - const result = await getNonceKeyCount(config, { - account: account.address, - }) - expect(result).toBe(0n) - }) - - describe('queryOptions', () => { - test('default', async () => { - const options = getNonceKeyCount.queryOptions(config, { - account: account.address, - }) - expect(await queryClient.fetchQuery(options)).toBe(0n) - }) - }) -}) - describe('watchNonceIncremented', () => { test('default', async () => { await connect(config, { @@ -98,48 +80,3 @@ describe('watchNonceIncremented', () => { unwatch() }) }) - -describe('watchActiveKeyCountChanged', () => { - test('default', async () => { - await connect(config, { - connector: config.connectors[0]!, - }) - - const events: any[] = [] - const unwatch = nonce.watchActiveKeyCountChanged(config, { - onActiveKeyCountChanged: (args) => { - events.push(args) - }, - }) - - const priorKeyCount = await getNonceKeyCount(config, { - account: account.address, - }) - - // First use of nonceKey 10 should increment active key count - await token.transferSync(config, { - to: account2.address, - amount: 1n, - token: 1n, - nonceKey: 10n, - nonce: 0, - }) - - // First use of nonceKey 11 should increment again - await token.transferSync(config, { - to: account2.address, - amount: 1n, - token: 1n, - nonceKey: 11n, - nonce: 0, - }) - - await new Promise((resolve) => setTimeout(resolve, 1000)) - - expect(events).toHaveLength(2) - expect(events[0]?.account).toBe(account.address) - expect(events[0]?.newCount - priorKeyCount).toBe(1n) - expect(events[1]?.newCount - priorKeyCount).toBe(2n) - unwatch() - }) -}) diff --git a/src/wagmi/Actions/nonce.ts b/src/wagmi/Actions/nonce.ts index 4f4981ed..354aad81 100644 --- a/src/wagmi/Actions/nonce.ts +++ b/src/wagmi/Actions/nonce.ts @@ -1,8 +1,8 @@ import type * as Query from '@tanstack/query-core' import type { Config } from '@wagmi/core' import type { ChainIdParameter } from '@wagmi/core/internal' +import { Actions } from 'viem/tempo' import type { PartialBy, RequiredBy } from '../../internal/types.js' -import * as viem_Actions from '../../viem/Actions/nonce.js' /** * Gets the nonce for an account and nonce key. @@ -10,11 +10,11 @@ import * as viem_Actions from '../../viem/Actions/nonce.js' * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -36,14 +36,14 @@ export function getNonce( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getNonce(client, rest) + return Actions.nonce.getNonce(client, rest) } export namespace getNonce { export type Parameters = ChainIdParameter & - viem_Actions.getNonce.Parameters + Actions.nonce.getNonce.Parameters - export type ReturnValue = viem_Actions.getNonce.ReturnValue + export type ReturnValue = Actions.nonce.getNonce.ReturnValue export function queryKey( parameters: PartialBy, 'account' | 'nonceKey'>, @@ -97,108 +97,17 @@ export namespace getNonce { } } -/** - * Gets the number of active nonce keys for an account. - * - * @example - * ```ts - * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/wagmi' - * - * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], - * transports: { - * [tempo.id]: http(), - * }, - * }) - * - * const count = await Actions.nonce.getNonceKeyCount(config, { - * account: '0x...', - * }) - * ``` - * - * @param config - Config. - * @param parameters - Parameters. - * @returns The number of active nonce keys. - */ -export function getNonceKeyCount( - config: config, - parameters: getNonceKeyCount.Parameters, -): Promise { - const { chainId, ...rest } = parameters - const client = config.getClient({ chainId }) - return viem_Actions.getNonceKeyCount(client, rest) -} - -export namespace getNonceKeyCount { - export type Parameters = ChainIdParameter & - viem_Actions.getNonceKeyCount.Parameters - - export type ReturnValue = viem_Actions.getNonceKeyCount.ReturnValue - - export function queryKey( - parameters: PartialBy, 'account'>, - ) { - return ['getNonceKeyCount', parameters] as const - } - - export type QueryKey = ReturnType< - typeof queryKey - > - - export function queryOptions( - config: Config, - parameters: queryOptions.Parameters, - ): queryOptions.ReturnValue { - const { query, ...rest } = parameters - return { - ...query, - queryKey: queryKey(rest), - async queryFn({ queryKey }) { - const [, { account, ...parameters }] = queryKey - if (!account) throw new Error('account is required.') - return await getNonceKeyCount(config, { account, ...parameters }) - }, - } - } - - export declare namespace queryOptions { - export type Parameters< - config extends Config, - selectData = getNonceKeyCount.ReturnValue, - > = PartialBy, 'account'> & { - query?: - | Omit, 'queryKey' | 'queryFn'> - | undefined - } - - export type ReturnValue< - config extends Config, - selectData = getNonceKeyCount.ReturnValue, - > = RequiredBy< - Query.QueryOptions< - getNonceKeyCount.ReturnValue, - Query.DefaultError, - selectData, - getNonceKeyCount.QueryKey - >, - 'queryKey' | 'queryFn' - > - } -} - /** * Watches for nonce incremented events. * * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -221,51 +130,10 @@ export function watchNonceIncremented( ): () => void { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchNonceIncremented(client, rest) + return Actions.nonce.watchNonceIncremented(client, rest) } export declare namespace watchNonceIncremented { export type Parameters = ChainIdParameter & - viem_Actions.watchNonceIncremented.Parameters -} - -/** - * Watches for active key count changed events. - * - * @example - * ```ts - * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' - * import { Actions } from 'tempo.ts/wagmi' - * - * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], - * transports: { - * [tempo.id]: http(), - * }, - * }) - * - * const unwatch = Actions.nonce.watchActiveKeyCountChanged(config, { - * onActiveKeyCountChanged: (args, log) => { - * console.log('Active key count changed:', args) - * }, - * }) - * ``` - * - * @param config - Config. - * @param parameters - Parameters. - * @returns A function to unsubscribe from the event. - */ -export function watchActiveKeyCountChanged( - config: config, - parameters: watchActiveKeyCountChanged.Parameters, -): () => void { - const { chainId, ...rest } = parameters - const client = config.getClient({ chainId }) - return viem_Actions.watchActiveKeyCountChanged(client, rest) -} - -export declare namespace watchActiveKeyCountChanged { - export type Parameters = ChainIdParameter & - viem_Actions.watchActiveKeyCountChanged.Parameters + Actions.nonce.watchNonceIncremented.Parameters } diff --git a/src/wagmi/Actions/policy.ts b/src/wagmi/Actions/policy.ts index e1a13447..7b151956 100644 --- a/src/wagmi/Actions/policy.ts +++ b/src/wagmi/Actions/policy.ts @@ -2,10 +2,8 @@ import type * as Query from '@tanstack/query-core' import { type Config, getConnectorClient } from '@wagmi/core' import type { ChainIdParameter, ConnectorParameter } from '@wagmi/core/internal' import type { Account } from 'viem' +import { Actions } from 'viem/tempo' import type { RequiredBy, UnionOmit } from '../../internal/types.js' -import * as viem_Actions from '../../viem/Actions/policy.js' - -export type { PolicyType } from '../../viem/Actions/policy.js' /** * Creates a new policy. @@ -13,11 +11,11 @@ export type { PolicyType } from '../../viem/Actions/policy.js' * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -35,7 +33,7 @@ export type { PolicyType } from '../../viem/Actions/policy.js' export async function create( config: config, parameters: create.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -45,20 +43,20 @@ export async function create( connector, }) - return viem_Actions.create(client, parameters as never) + return Actions.policy.create(client, parameters as never) } export declare namespace create { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.create.Parameters, + Actions.policy.create.Parameters, 'chain' | 'admin' > - export type ReturnValue = viem_Actions.create.ReturnValue + export type ReturnValue = Actions.policy.create.ReturnValue - export type ErrorType = viem_Actions.create.ErrorType + export type ErrorType = Actions.policy.create.ErrorType } /** @@ -70,11 +68,11 @@ export declare namespace create { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -92,7 +90,7 @@ export declare namespace create { export async function createSync( config: config, parameters: createSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -102,20 +100,20 @@ export async function createSync( connector, }) - return viem_Actions.createSync(client, parameters as never) + return Actions.policy.createSync(client, parameters as never) } export declare namespace createSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.createSync.Parameters, + Actions.policy.createSync.Parameters, 'chain' | 'admin' > - export type ReturnValue = viem_Actions.createSync.ReturnValue + export type ReturnValue = Actions.policy.createSync.ReturnValue - export type ErrorType = viem_Actions.createSync.ErrorType + export type ErrorType = Actions.policy.createSync.ErrorType } /** @@ -124,11 +122,11 @@ export declare namespace createSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -147,7 +145,7 @@ export declare namespace createSync { export async function setAdmin( config: config, parameters: setAdmin.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -157,20 +155,20 @@ export async function setAdmin( connector, }) - return viem_Actions.setAdmin(client, parameters as never) + return Actions.policy.setAdmin(client, parameters as never) } export declare namespace setAdmin { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.setAdmin.Parameters, + Actions.policy.setAdmin.Parameters, 'chain' > - export type ReturnValue = viem_Actions.setAdmin.ReturnValue + export type ReturnValue = Actions.policy.setAdmin.ReturnValue - export type ErrorType = viem_Actions.setAdmin.ErrorType + export type ErrorType = Actions.policy.setAdmin.ErrorType } /** @@ -182,11 +180,11 @@ export declare namespace setAdmin { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -205,7 +203,7 @@ export declare namespace setAdmin { export async function setAdminSync( config: config, parameters: setAdminSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -215,20 +213,20 @@ export async function setAdminSync( connector, }) - return viem_Actions.setAdminSync(client, parameters as never) + return Actions.policy.setAdminSync(client, parameters as never) } export declare namespace setAdminSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.setAdminSync.Parameters, + Actions.policy.setAdminSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.setAdminSync.ReturnValue + export type ReturnValue = Actions.policy.setAdminSync.ReturnValue - export type ErrorType = viem_Actions.setAdminSync.ErrorType + export type ErrorType = Actions.policy.setAdminSync.ErrorType } /** @@ -237,11 +235,11 @@ export declare namespace setAdminSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -261,7 +259,7 @@ export declare namespace setAdminSync { export async function modifyWhitelist( config: config, parameters: modifyWhitelist.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -271,23 +269,23 @@ export async function modifyWhitelist( connector, }) - return viem_Actions.modifyWhitelist(client, parameters as never) + return Actions.policy.modifyWhitelist(client, parameters as never) } export declare namespace modifyWhitelist { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.modifyWhitelist.Parameters< + Actions.policy.modifyWhitelist.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.modifyWhitelist.ReturnValue + export type ReturnValue = Actions.policy.modifyWhitelist.ReturnValue - export type ErrorType = viem_Actions.modifyWhitelist.ErrorType + export type ErrorType = Actions.policy.modifyWhitelist.ErrorType } /** @@ -299,11 +297,11 @@ export declare namespace modifyWhitelist { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -323,7 +321,7 @@ export declare namespace modifyWhitelist { export async function modifyWhitelistSync( config: config, parameters: modifyWhitelistSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -333,23 +331,23 @@ export async function modifyWhitelistSync( connector, }) - return viem_Actions.modifyWhitelistSync(client, parameters as never) + return Actions.policy.modifyWhitelistSync(client, parameters as never) } export declare namespace modifyWhitelistSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.modifyWhitelistSync.Parameters< + Actions.policy.modifyWhitelistSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.modifyWhitelistSync.ReturnValue + export type ReturnValue = Actions.policy.modifyWhitelistSync.ReturnValue - export type ErrorType = viem_Actions.modifyWhitelistSync.ErrorType + export type ErrorType = Actions.policy.modifyWhitelistSync.ErrorType } /** @@ -358,11 +356,11 @@ export declare namespace modifyWhitelistSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -382,7 +380,7 @@ export declare namespace modifyWhitelistSync { export async function modifyBlacklist( config: config, parameters: modifyBlacklist.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -392,23 +390,23 @@ export async function modifyBlacklist( connector, }) - return viem_Actions.modifyBlacklist(client, parameters as never) + return Actions.policy.modifyBlacklist(client, parameters as never) } export declare namespace modifyBlacklist { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.modifyBlacklist.Parameters< + Actions.policy.modifyBlacklist.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.modifyBlacklist.ReturnValue + export type ReturnValue = Actions.policy.modifyBlacklist.ReturnValue - export type ErrorType = viem_Actions.modifyBlacklist.ErrorType + export type ErrorType = Actions.policy.modifyBlacklist.ErrorType } /** @@ -420,11 +418,11 @@ export declare namespace modifyBlacklist { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -444,7 +442,7 @@ export declare namespace modifyBlacklist { export async function modifyBlacklistSync( config: config, parameters: modifyBlacklistSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -454,23 +452,23 @@ export async function modifyBlacklistSync( connector, }) - return viem_Actions.modifyBlacklistSync(client, parameters as never) + return Actions.policy.modifyBlacklistSync(client, parameters as never) } export declare namespace modifyBlacklistSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.modifyBlacklistSync.Parameters< + Actions.policy.modifyBlacklistSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.modifyBlacklistSync.ReturnValue + export type ReturnValue = Actions.policy.modifyBlacklistSync.ReturnValue - export type ErrorType = viem_Actions.modifyBlacklistSync.ErrorType + export type ErrorType = Actions.policy.modifyBlacklistSync.ErrorType } /** @@ -479,11 +477,11 @@ export declare namespace modifyBlacklistSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -504,14 +502,14 @@ export function getData( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getData(client, rest) + return Actions.policy.getData(client, rest) } export namespace getData { export type Parameters = ChainIdParameter & - viem_Actions.getData.Parameters + Actions.policy.getData.Parameters - export type ReturnValue = viem_Actions.getData.ReturnValue + export type ReturnValue = Actions.policy.getData.ReturnValue export function queryKey( parameters: Parameters, @@ -569,11 +567,11 @@ export namespace getData { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -595,14 +593,14 @@ export function isAuthorized( ): Promise { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.isAuthorized(client, rest) + return Actions.policy.isAuthorized(client, rest) } export namespace isAuthorized { export type Parameters = ChainIdParameter & - viem_Actions.isAuthorized.Parameters + Actions.policy.isAuthorized.Parameters - export type ReturnValue = viem_Actions.isAuthorized.ReturnValue + export type ReturnValue = Actions.policy.isAuthorized.ReturnValue export function queryKey( parameters: Parameters, @@ -660,11 +658,11 @@ export namespace isAuthorized { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -687,12 +685,12 @@ export function watchCreate( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchCreate(client, rest) + return Actions.policy.watchCreate(client, rest) } export declare namespace watchCreate { export type Parameters = ChainIdParameter & - viem_Actions.watchCreate.Parameters + Actions.policy.watchCreate.Parameters } /** @@ -701,11 +699,11 @@ export declare namespace watchCreate { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -728,12 +726,12 @@ export function watchAdminUpdated( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchAdminUpdated(client, rest) + return Actions.policy.watchAdminUpdated(client, rest) } export declare namespace watchAdminUpdated { export type Parameters = ChainIdParameter & - viem_Actions.watchAdminUpdated.Parameters + Actions.policy.watchAdminUpdated.Parameters } /** @@ -742,11 +740,11 @@ export declare namespace watchAdminUpdated { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -769,12 +767,12 @@ export function watchWhitelistUpdated( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchWhitelistUpdated(client, rest) + return Actions.policy.watchWhitelistUpdated(client, rest) } export declare namespace watchWhitelistUpdated { export type Parameters = ChainIdParameter & - viem_Actions.watchWhitelistUpdated.Parameters + Actions.policy.watchWhitelistUpdated.Parameters } /** @@ -783,11 +781,11 @@ export declare namespace watchWhitelistUpdated { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -810,10 +808,10 @@ export function watchBlacklistUpdated( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchBlacklistUpdated(client, rest) + return Actions.policy.watchBlacklistUpdated(client, rest) } export declare namespace watchBlacklistUpdated { export type Parameters = ChainIdParameter & - viem_Actions.watchBlacklistUpdated.Parameters + Actions.policy.watchBlacklistUpdated.Parameters } diff --git a/src/wagmi/Actions/reward.ts b/src/wagmi/Actions/reward.ts index 83fb23e1..fcd16230 100644 --- a/src/wagmi/Actions/reward.ts +++ b/src/wagmi/Actions/reward.ts @@ -2,8 +2,8 @@ import type * as Query from '@tanstack/query-core' import { type Config, getConnectorClient } from '@wagmi/core' import type { ChainIdParameter, ConnectorParameter } from '@wagmi/core/internal' import type { Account } from 'viem' +import { Actions } from 'viem/tempo' import type { RequiredBy, UnionOmit } from '../../internal/types.js' -import * as viem_Actions from '../../viem/Actions/reward.js' /** * Claims accumulated rewards for a recipient. @@ -11,11 +11,11 @@ import * as viem_Actions from '../../viem/Actions/reward.js' * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -33,7 +33,7 @@ import * as viem_Actions from '../../viem/Actions/reward.js' export async function claim( config: config, parameters: claim.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -43,7 +43,7 @@ export async function claim( connector, }) - return viem_Actions.claim(client, parameters as never) + return Actions.reward.claim(client, parameters as never) } export declare namespace claim { @@ -51,13 +51,13 @@ export declare namespace claim { ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.claim.Parameters, + Actions.reward.claim.Parameters, 'chain' > - export type ReturnValue = viem_Actions.claim.ReturnValue + export type ReturnValue = Actions.reward.claim.ReturnValue - export type ErrorType = viem_Actions.claim.ErrorType + export type ErrorType = Actions.reward.claim.ErrorType } /** @@ -66,11 +66,11 @@ export declare namespace claim { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -88,7 +88,7 @@ export declare namespace claim { export async function claimSync( config: config, parameters: claimSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -98,7 +98,7 @@ export async function claimSync( connector, }) - return viem_Actions.claimSync(client, parameters as never) + return Actions.reward.claimSync(client, parameters as never) } export declare namespace claimSync { @@ -106,13 +106,13 @@ export declare namespace claimSync { ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.claimSync.Parameters, + Actions.reward.claimSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.claimSync.ReturnValue + export type ReturnValue = Actions.reward.claimSync.ReturnValue - export type ErrorType = viem_Actions.claimSync.ErrorType + export type ErrorType = Actions.reward.claimSync.ErrorType } /** @@ -121,11 +121,11 @@ export declare namespace claimSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -146,14 +146,14 @@ export function getTotalPerSecond( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getTotalPerSecond(client, rest) + return Actions.reward.getTotalPerSecond(client, rest) } export namespace getTotalPerSecond { export type Parameters = ChainIdParameter & - viem_Actions.getTotalPerSecond.Parameters + Actions.reward.getTotalPerSecond.Parameters - export type ReturnValue = viem_Actions.getTotalPerSecond.ReturnValue + export type ReturnValue = Actions.reward.getTotalPerSecond.ReturnValue export function queryKey( parameters: Parameters, @@ -211,11 +211,11 @@ export namespace getTotalPerSecond { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -237,14 +237,14 @@ export function getUserRewardInfo( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getUserRewardInfo(client, rest) + return Actions.reward.getUserRewardInfo(client, rest) } export namespace getUserRewardInfo { export type Parameters = ChainIdParameter & - viem_Actions.getUserRewardInfo.Parameters + Actions.reward.getUserRewardInfo.Parameters - export type ReturnValue = viem_Actions.getUserRewardInfo.ReturnValue + export type ReturnValue = Actions.reward.getUserRewardInfo.ReturnValue export function queryKey( parameters: Parameters, @@ -302,11 +302,11 @@ export namespace getUserRewardInfo { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -325,7 +325,7 @@ export namespace getUserRewardInfo { export async function setRecipient( config: config, parameters: setRecipient.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -335,7 +335,7 @@ export async function setRecipient( connector, }) - return viem_Actions.setRecipient(client, parameters as never) + return Actions.reward.setRecipient(client, parameters as never) } export declare namespace setRecipient { @@ -343,13 +343,16 @@ export declare namespace setRecipient { ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.setRecipient.Parameters, + Actions.reward.setRecipient.Parameters< + config['chains'][number], + Account + >, 'chain' > - export type ReturnValue = viem_Actions.setRecipient.ReturnValue + export type ReturnValue = Actions.reward.setRecipient.ReturnValue - export type ErrorType = viem_Actions.setRecipient.ErrorType + export type ErrorType = Actions.reward.setRecipient.ErrorType } /** @@ -358,11 +361,11 @@ export declare namespace setRecipient { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -381,7 +384,7 @@ export declare namespace setRecipient { export async function setRecipientSync( config: config, parameters: setRecipientSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -391,7 +394,7 @@ export async function setRecipientSync( connector, }) - return viem_Actions.setRecipientSync(client, parameters as never) + return Actions.reward.setRecipientSync(client, parameters as never) } export declare namespace setRecipientSync { @@ -399,16 +402,16 @@ export declare namespace setRecipientSync { ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.setRecipientSync.Parameters< + Actions.reward.setRecipientSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.setRecipientSync.ReturnValue + export type ReturnValue = Actions.reward.setRecipientSync.ReturnValue - export type ErrorType = viem_Actions.setRecipientSync.ErrorType + export type ErrorType = Actions.reward.setRecipientSync.ErrorType } /** @@ -417,11 +420,11 @@ export declare namespace setRecipientSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -441,7 +444,7 @@ export declare namespace setRecipientSync { export async function start( config: config, parameters: start.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -451,7 +454,7 @@ export async function start( connector, }) - return viem_Actions.start(client, parameters as never) + return Actions.reward.start(client, parameters as never) } export declare namespace start { @@ -459,13 +462,13 @@ export declare namespace start { ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.start.Parameters, + Actions.reward.start.Parameters, 'chain' > - export type ReturnValue = viem_Actions.start.ReturnValue + export type ReturnValue = Actions.reward.start.ReturnValue - export type ErrorType = viem_Actions.start.ErrorType + export type ErrorType = Actions.reward.start.ErrorType } /** @@ -474,11 +477,11 @@ export declare namespace start { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -498,7 +501,7 @@ export declare namespace start { export async function startSync( config: config, parameters: startSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -508,7 +511,7 @@ export async function startSync( connector, }) - return viem_Actions.startSync(client, parameters as never) + return Actions.reward.startSync(client, parameters as never) } export declare namespace startSync { @@ -516,13 +519,13 @@ export declare namespace startSync { ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.startSync.Parameters, + Actions.reward.startSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.startSync.ReturnValue + export type ReturnValue = Actions.reward.startSync.ReturnValue - export type ErrorType = viem_Actions.startSync.ErrorType + export type ErrorType = Actions.reward.startSync.ErrorType } /** @@ -531,11 +534,11 @@ export declare namespace startSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -559,12 +562,12 @@ export function watchRewardScheduled( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchRewardScheduled(client, rest) + return Actions.reward.watchRewardScheduled(client, rest) } export declare namespace watchRewardScheduled { export type Parameters = ChainIdParameter & - viem_Actions.watchRewardScheduled.Parameters + Actions.reward.watchRewardScheduled.Parameters } /** @@ -573,11 +576,11 @@ export declare namespace watchRewardScheduled { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -601,10 +604,10 @@ export function watchRewardRecipientSet( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchRewardRecipientSet(client, rest) + return Actions.reward.watchRewardRecipientSet(client, rest) } export declare namespace watchRewardRecipientSet { export type Parameters = ChainIdParameter & - viem_Actions.watchRewardRecipientSet.Parameters + Actions.reward.watchRewardRecipientSet.Parameters } diff --git a/src/wagmi/Actions/token.ts b/src/wagmi/Actions/token.ts index d1e37f64..da8e0c21 100644 --- a/src/wagmi/Actions/token.ts +++ b/src/wagmi/Actions/token.ts @@ -2,8 +2,8 @@ import type * as Query from '@tanstack/query-core' import { type Config, getConnectorClient } from '@wagmi/core' import type { ChainIdParameter, ConnectorParameter } from '@wagmi/core/internal' import type { Account } from 'viem' +import { Actions } from 'viem/tempo' import type { RequiredBy, UnionOmit } from '../../internal/types.js' -import * as viem_Actions from '../../viem/Actions/token.js' /** * Approves a spender to transfer TIP20 tokens on behalf of the caller. @@ -11,11 +11,11 @@ import * as viem_Actions from '../../viem/Actions/token.js' * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -34,7 +34,7 @@ import * as viem_Actions from '../../viem/Actions/token.js' export async function approve( config: config, parameters: approve.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -44,20 +44,20 @@ export async function approve( connector, }) - return viem_Actions.approve(client, parameters as never) + return Actions.token.approve(client, parameters as never) } export declare namespace approve { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.approve.Parameters, + Actions.token.approve.Parameters, 'chain' > - export type ReturnValue = viem_Actions.approve.ReturnValue + export type ReturnValue = Actions.token.approve.ReturnValue - export type ErrorType = viem_Actions.approve.ErrorType + export type ErrorType = Actions.token.approve.ErrorType } /** @@ -69,11 +69,11 @@ export declare namespace approve { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -92,7 +92,7 @@ export declare namespace approve { export async function approveSync( config: config, parameters: approveSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -102,20 +102,20 @@ export async function approveSync( connector, }) - return viem_Actions.approveSync(client, parameters as never) + return Actions.token.approveSync(client, parameters as never) } export declare namespace approveSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.approveSync.Parameters, + Actions.token.approveSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.approveSync.ReturnValue + export type ReturnValue = Actions.token.approveSync.ReturnValue - export type ErrorType = viem_Actions.approveSync.ErrorType + export type ErrorType = Actions.token.approveSync.ErrorType } /** @@ -124,11 +124,11 @@ export declare namespace approveSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -147,7 +147,7 @@ export declare namespace approveSync { export async function burn( config: config, parameters: burn.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -157,20 +157,20 @@ export async function burn( connector, }) - return viem_Actions.burn(client, parameters as never) + return Actions.token.burn(client, parameters as never) } export declare namespace burn { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.burn.Parameters, + Actions.token.burn.Parameters, 'chain' > - export type ReturnValue = viem_Actions.burn.ReturnValue + export type ReturnValue = Actions.token.burn.ReturnValue - export type ErrorType = viem_Actions.burn.ErrorType + export type ErrorType = Actions.token.burn.ErrorType } /** @@ -179,11 +179,11 @@ export declare namespace burn { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -203,7 +203,7 @@ export declare namespace burn { export async function burnBlocked( config: config, parameters: burnBlocked.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -213,20 +213,20 @@ export async function burnBlocked( connector, }) - return await viem_Actions.burnBlocked(client, parameters as never) + return await Actions.token.burnBlocked(client, parameters as never) } export declare namespace burnBlocked { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.burnBlocked.Parameters, + Actions.token.burnBlocked.Parameters, 'chain' > - export type ReturnValue = viem_Actions.burnBlocked.ReturnValue + export type ReturnValue = Actions.token.burnBlocked.ReturnValue - export type ErrorType = viem_Actions.burnBlocked.ErrorType + export type ErrorType = Actions.token.burnBlocked.ErrorType } /** @@ -238,11 +238,11 @@ export declare namespace burnBlocked { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -262,7 +262,7 @@ export declare namespace burnBlocked { export async function burnBlockedSync( config: config, parameters: burnBlockedSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -272,23 +272,23 @@ export async function burnBlockedSync( connector, }) - return viem_Actions.burnBlockedSync(client, parameters as never) + return Actions.token.burnBlockedSync(client, parameters as never) } export declare namespace burnBlockedSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.burnBlockedSync.Parameters< + Actions.token.burnBlockedSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.burnBlockedSync.ReturnValue + export type ReturnValue = Actions.token.burnBlockedSync.ReturnValue - export type ErrorType = viem_Actions.burnBlockedSync.ErrorType + export type ErrorType = Actions.token.burnBlockedSync.ErrorType } /** @@ -300,11 +300,11 @@ export declare namespace burnBlockedSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -323,7 +323,7 @@ export declare namespace burnBlockedSync { export async function burnSync( config: config, parameters: burnSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -333,20 +333,20 @@ export async function burnSync( connector, }) - return viem_Actions.burnSync(client, parameters as never) + return Actions.token.burnSync(client, parameters as never) } export declare namespace burnSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.burnSync.Parameters, + Actions.token.burnSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.burnSync.ReturnValue + export type ReturnValue = Actions.token.burnSync.ReturnValue - export type ErrorType = viem_Actions.burnSync.ErrorType + export type ErrorType = Actions.token.burnSync.ErrorType } /** @@ -355,11 +355,11 @@ export declare namespace burnSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -378,7 +378,7 @@ export declare namespace burnSync { export async function changeTransferPolicy( config: config, parameters: changeTransferPolicy.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -388,23 +388,23 @@ export async function changeTransferPolicy( connector, }) - return viem_Actions.changeTransferPolicy(client, parameters as never) + return Actions.token.changeTransferPolicy(client, parameters as never) } export declare namespace changeTransferPolicy { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.changeTransferPolicy.Parameters< + Actions.token.changeTransferPolicy.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.changeTransferPolicy.ReturnValue + export type ReturnValue = Actions.token.changeTransferPolicy.ReturnValue - export type ErrorType = viem_Actions.changeTransferPolicy.ErrorType + export type ErrorType = Actions.token.changeTransferPolicy.ErrorType } /** @@ -416,11 +416,11 @@ export declare namespace changeTransferPolicy { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -439,7 +439,7 @@ export declare namespace changeTransferPolicy { export async function changeTransferPolicySync( config: config, parameters: changeTransferPolicySync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -449,23 +449,23 @@ export async function changeTransferPolicySync( connector, }) - return viem_Actions.changeTransferPolicySync(client, parameters as never) + return Actions.token.changeTransferPolicySync(client, parameters as never) } export declare namespace changeTransferPolicySync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.changeTransferPolicySync.Parameters< + Actions.token.changeTransferPolicySync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.changeTransferPolicySync.ReturnValue + export type ReturnValue = Actions.token.changeTransferPolicySync.ReturnValue - export type ErrorType = viem_Actions.changeTransferPolicySync.ErrorType + export type ErrorType = Actions.token.changeTransferPolicySync.ErrorType } /** @@ -474,11 +474,11 @@ export declare namespace changeTransferPolicySync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -498,7 +498,7 @@ export declare namespace changeTransferPolicySync { export async function create( config: config, parameters: create.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -508,20 +508,20 @@ export async function create( connector, }) - return viem_Actions.create(client, parameters as never) + return Actions.token.create(client, parameters as never) } export declare namespace create { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.create.Parameters, + Actions.token.create.Parameters, 'chain' > - export type ReturnValue = viem_Actions.create.ReturnValue + export type ReturnValue = Actions.token.create.ReturnValue - export type ErrorType = viem_Actions.create.ErrorType + export type ErrorType = Actions.token.create.ErrorType } /** @@ -533,11 +533,11 @@ export declare namespace create { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -557,7 +557,7 @@ export declare namespace create { export async function createSync( config: config, parameters: createSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -567,20 +567,20 @@ export async function createSync( connector, }) - return viem_Actions.createSync(client, parameters as never) + return Actions.token.createSync(client, parameters as never) } export declare namespace createSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.createSync.Parameters, + Actions.token.createSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.createSync.ReturnValue + export type ReturnValue = Actions.token.createSync.ReturnValue - export type ErrorType = viem_Actions.createSync.ErrorType + export type ErrorType = Actions.token.createSync.ErrorType } /** @@ -589,11 +589,11 @@ export declare namespace createSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -611,7 +611,7 @@ export declare namespace createSync { export async function updateQuoteToken( config: config, parameters: updateQuoteToken.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -621,23 +621,23 @@ export async function updateQuoteToken( connector, }) - return viem_Actions.updateQuoteToken(client, parameters as never) + return Actions.token.updateQuoteToken(client, parameters as never) } export declare namespace updateQuoteToken { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.updateQuoteToken.Parameters< + Actions.token.updateQuoteToken.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.updateQuoteToken.ReturnValue + export type ReturnValue = Actions.token.updateQuoteToken.ReturnValue - export type ErrorType = viem_Actions.updateQuoteToken.ErrorType + export type ErrorType = Actions.token.updateQuoteToken.ErrorType } /** @@ -649,11 +649,11 @@ export declare namespace updateQuoteToken { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -671,7 +671,7 @@ export declare namespace updateQuoteToken { export async function updateQuoteTokenSync( config: config, parameters: updateQuoteTokenSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -681,23 +681,23 @@ export async function updateQuoteTokenSync( connector, }) - return viem_Actions.updateQuoteTokenSync(client, parameters as never) + return Actions.token.updateQuoteTokenSync(client, parameters as never) } export declare namespace updateQuoteTokenSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.updateQuoteTokenSync.Parameters< + Actions.token.updateQuoteTokenSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.updateQuoteTokenSync.ReturnValue + export type ReturnValue = Actions.token.updateQuoteTokenSync.ReturnValue - export type ErrorType = viem_Actions.updateQuoteTokenSync.ErrorType + export type ErrorType = Actions.token.updateQuoteTokenSync.ErrorType } /** @@ -706,11 +706,11 @@ export declare namespace updateQuoteTokenSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -732,14 +732,14 @@ export function getAllowance( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getAllowance(client, rest) + return Actions.token.getAllowance(client, rest) } export namespace getAllowance { export type Parameters = ChainIdParameter & - viem_Actions.getAllowance.Parameters + Actions.token.getAllowance.Parameters - export type ReturnValue = viem_Actions.getAllowance.ReturnValue + export type ReturnValue = Actions.token.getAllowance.ReturnValue export function queryKey( parameters: Parameters, @@ -797,11 +797,11 @@ export namespace getAllowance { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -822,14 +822,14 @@ export function getBalance( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getBalance(client, rest as never) + return Actions.token.getBalance(client, rest as never) } export namespace getBalance { export type Parameters = ChainIdParameter & - viem_Actions.getBalance.Parameters + Actions.token.getBalance.Parameters - export type ReturnValue = viem_Actions.getBalance.ReturnValue + export type ReturnValue = Actions.token.getBalance.ReturnValue export function queryKey( parameters: Parameters, @@ -887,11 +887,11 @@ export namespace getBalance { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -912,14 +912,14 @@ export function getMetadata( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getMetadata(client, rest) + return Actions.token.getMetadata(client, rest) } export namespace getMetadata { export type Parameters = ChainIdParameter & - viem_Actions.getMetadata.Parameters + Actions.token.getMetadata.Parameters - export type ReturnValue = viem_Actions.getMetadata.ReturnValue + export type ReturnValue = Actions.token.getMetadata.ReturnValue export function queryKey( parameters: Parameters, @@ -977,11 +977,11 @@ export namespace getMetadata { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1003,14 +1003,14 @@ export function getRoleAdmin( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.getRoleAdmin(client, rest) + return Actions.token.getRoleAdmin(client, rest) } export namespace getRoleAdmin { export type Parameters = ChainIdParameter & - viem_Actions.getRoleAdmin.Parameters + Actions.token.getRoleAdmin.Parameters - export type ReturnValue = viem_Actions.getRoleAdmin.ReturnValue + export type ReturnValue = Actions.token.getRoleAdmin.ReturnValue export function queryKey( parameters: Parameters, @@ -1068,11 +1068,11 @@ export namespace getRoleAdmin { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1092,7 +1092,7 @@ export namespace getRoleAdmin { export async function grantRoles( config: config, parameters: grantRoles.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1102,20 +1102,20 @@ export async function grantRoles( connector, }) - return viem_Actions.grantRoles(client, parameters as never) + return Actions.token.grantRoles(client, parameters as never) } export declare namespace grantRoles { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.grantRoles.Parameters, + Actions.token.grantRoles.Parameters, 'chain' > - export type ReturnValue = viem_Actions.grantRoles.ReturnValue + export type ReturnValue = Actions.token.grantRoles.ReturnValue - export type ErrorType = viem_Actions.grantRoles.ErrorType + export type ErrorType = Actions.token.grantRoles.ErrorType } /** @@ -1127,11 +1127,11 @@ export declare namespace grantRoles { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1151,7 +1151,7 @@ export declare namespace grantRoles { export async function grantRolesSync( config: config, parameters: grantRolesSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1161,20 +1161,23 @@ export async function grantRolesSync( connector, }) - return viem_Actions.grantRolesSync(client, parameters as never) + return Actions.token.grantRolesSync(client, parameters as never) } export declare namespace grantRolesSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.grantRolesSync.Parameters, + Actions.token.grantRolesSync.Parameters< + config['chains'][number], + Account + >, 'chain' > - export type ReturnValue = viem_Actions.grantRolesSync.ReturnValue + export type ReturnValue = Actions.token.grantRolesSync.ReturnValue - export type ErrorType = viem_Actions.grantRolesSync.ErrorType + export type ErrorType = Actions.token.grantRolesSync.ErrorType } /** @@ -1183,11 +1186,11 @@ export declare namespace grantRolesSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1210,14 +1213,14 @@ export function hasRole( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.hasRole(client, rest) + return Actions.token.hasRole(client, rest) } export namespace hasRole { export type Parameters = ChainIdParameter & - viem_Actions.hasRole.Parameters + Actions.token.hasRole.Parameters - export type ReturnValue = viem_Actions.hasRole.ReturnValue + export type ReturnValue = Actions.token.hasRole.ReturnValue export function queryKey( parameters: Parameters, @@ -1275,11 +1278,11 @@ export namespace hasRole { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1299,7 +1302,7 @@ export namespace hasRole { export async function mint( config: config, parameters: mint.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1309,20 +1312,20 @@ export async function mint( connector, }) - return viem_Actions.mint(client, parameters as never) + return Actions.token.mint(client, parameters as never) } export declare namespace mint { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.mint.Parameters, + Actions.token.mint.Parameters, 'chain' > - export type ReturnValue = viem_Actions.mint.ReturnValue + export type ReturnValue = Actions.token.mint.ReturnValue - export type ErrorType = viem_Actions.mint.ErrorType + export type ErrorType = Actions.token.mint.ErrorType } /** @@ -1334,11 +1337,11 @@ export declare namespace mint { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1358,7 +1361,7 @@ export declare namespace mint { export async function mintSync( config: config, parameters: mintSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1368,20 +1371,20 @@ export async function mintSync( connector, }) - return viem_Actions.mintSync(client, parameters as never) + return Actions.token.mintSync(client, parameters as never) } export declare namespace mintSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.mintSync.Parameters, + Actions.token.mintSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.mintSync.ReturnValue + export type ReturnValue = Actions.token.mintSync.ReturnValue - export type ErrorType = viem_Actions.mintSync.ErrorType + export type ErrorType = Actions.token.mintSync.ErrorType } /** @@ -1390,11 +1393,11 @@ export declare namespace mintSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1412,7 +1415,7 @@ export declare namespace mintSync { export async function pause( config: config, parameters: pause.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1422,20 +1425,20 @@ export async function pause( connector, }) - return viem_Actions.pause(client, parameters as never) + return Actions.token.pause(client, parameters as never) } export declare namespace pause { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.pause.Parameters, + Actions.token.pause.Parameters, 'chain' > - export type ReturnValue = viem_Actions.pause.ReturnValue + export type ReturnValue = Actions.token.pause.ReturnValue - export type ErrorType = viem_Actions.pause.ErrorType + export type ErrorType = Actions.token.pause.ErrorType } /** @@ -1447,11 +1450,11 @@ export declare namespace pause { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1469,7 +1472,7 @@ export declare namespace pause { export async function pauseSync( config: config, parameters: pauseSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1479,20 +1482,20 @@ export async function pauseSync( connector, }) - return viem_Actions.pauseSync(client, parameters as never) + return Actions.token.pauseSync(client, parameters as never) } export declare namespace pauseSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.pauseSync.Parameters, + Actions.token.pauseSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.pauseSync.ReturnValue + export type ReturnValue = Actions.token.pauseSync.ReturnValue - export type ErrorType = viem_Actions.pauseSync.ErrorType + export type ErrorType = Actions.token.pauseSync.ErrorType } /** @@ -1501,11 +1504,11 @@ export declare namespace pauseSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1524,7 +1527,7 @@ export declare namespace pauseSync { export async function renounceRoles( config: config, parameters: renounceRoles.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1534,20 +1537,20 @@ export async function renounceRoles( connector, }) - return viem_Actions.renounceRoles(client, parameters as never) + return Actions.token.renounceRoles(client, parameters as never) } export declare namespace renounceRoles { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.renounceRoles.Parameters, + Actions.token.renounceRoles.Parameters, 'chain' > - export type ReturnValue = viem_Actions.renounceRoles.ReturnValue + export type ReturnValue = Actions.token.renounceRoles.ReturnValue - export type ErrorType = viem_Actions.renounceRoles.ErrorType + export type ErrorType = Actions.token.renounceRoles.ErrorType } /** @@ -1559,11 +1562,11 @@ export declare namespace renounceRoles { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1582,7 +1585,7 @@ export declare namespace renounceRoles { export async function renounceRolesSync( config: config, parameters: renounceRolesSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1592,23 +1595,23 @@ export async function renounceRolesSync( connector, }) - return viem_Actions.renounceRolesSync(client, parameters as never) + return Actions.token.renounceRolesSync(client, parameters as never) } export declare namespace renounceRolesSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.renounceRolesSync.Parameters< + Actions.token.renounceRolesSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.renounceRolesSync.ReturnValue + export type ReturnValue = Actions.token.renounceRolesSync.ReturnValue - export type ErrorType = viem_Actions.renounceRolesSync.ErrorType + export type ErrorType = Actions.token.renounceRolesSync.ErrorType } /** @@ -1617,11 +1620,11 @@ export declare namespace renounceRolesSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1641,7 +1644,7 @@ export declare namespace renounceRolesSync { export async function revokeRoles( config: config, parameters: revokeRoles.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1651,20 +1654,20 @@ export async function revokeRoles( connector, }) - return viem_Actions.revokeRoles(client, parameters as never) + return Actions.token.revokeRoles(client, parameters as never) } export declare namespace revokeRoles { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.revokeRoles.Parameters, + Actions.token.revokeRoles.Parameters, 'chain' > - export type ReturnValue = viem_Actions.revokeRoles.ReturnValue + export type ReturnValue = Actions.token.revokeRoles.ReturnValue - export type ErrorType = viem_Actions.revokeRoles.ErrorType + export type ErrorType = Actions.token.revokeRoles.ErrorType } /** @@ -1676,11 +1679,11 @@ export declare namespace revokeRoles { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1700,7 +1703,7 @@ export declare namespace revokeRoles { export async function revokeRolesSync( config: config, parameters: revokeRolesSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1710,23 +1713,23 @@ export async function revokeRolesSync( connector, }) - return viem_Actions.revokeRolesSync(client, parameters as never) + return Actions.token.revokeRolesSync(client, parameters as never) } export declare namespace revokeRolesSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.revokeRolesSync.Parameters< + Actions.token.revokeRolesSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.revokeRolesSync.ReturnValue + export type ReturnValue = Actions.token.revokeRolesSync.ReturnValue - export type ErrorType = viem_Actions.revokeRolesSync.ErrorType + export type ErrorType = Actions.token.revokeRolesSync.ErrorType } /** @@ -1735,11 +1738,11 @@ export declare namespace revokeRolesSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1759,7 +1762,7 @@ export declare namespace revokeRolesSync { export async function setRoleAdmin( config: config, parameters: setRoleAdmin.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1769,20 +1772,20 @@ export async function setRoleAdmin( connector, }) - return viem_Actions.setRoleAdmin(client, parameters as never) + return Actions.token.setRoleAdmin(client, parameters as never) } export declare namespace setRoleAdmin { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.setRoleAdmin.Parameters, + Actions.token.setRoleAdmin.Parameters, 'chain' > - export type ReturnValue = viem_Actions.setRoleAdmin.ReturnValue + export type ReturnValue = Actions.token.setRoleAdmin.ReturnValue - export type ErrorType = viem_Actions.setRoleAdmin.ErrorType + export type ErrorType = Actions.token.setRoleAdmin.ErrorType } /** @@ -1794,11 +1797,11 @@ export declare namespace setRoleAdmin { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1818,7 +1821,7 @@ export declare namespace setRoleAdmin { export async function setRoleAdminSync( config: config, parameters: setRoleAdminSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1828,23 +1831,23 @@ export async function setRoleAdminSync( connector, }) - return viem_Actions.setRoleAdminSync(client, parameters as never) + return Actions.token.setRoleAdminSync(client, parameters as never) } export declare namespace setRoleAdminSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.setRoleAdminSync.Parameters< + Actions.token.setRoleAdminSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.setRoleAdminSync.ReturnValue + export type ReturnValue = Actions.token.setRoleAdminSync.ReturnValue - export type ErrorType = viem_Actions.setRoleAdminSync.ErrorType + export type ErrorType = Actions.token.setRoleAdminSync.ErrorType } /** @@ -1853,11 +1856,11 @@ export declare namespace setRoleAdminSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1876,7 +1879,7 @@ export declare namespace setRoleAdminSync { export async function setSupplyCap( config: config, parameters: setSupplyCap.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1886,20 +1889,20 @@ export async function setSupplyCap( connector, }) - return viem_Actions.setSupplyCap(client, parameters as never) + return Actions.token.setSupplyCap(client, parameters as never) } export declare namespace setSupplyCap { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.setSupplyCap.Parameters, + Actions.token.setSupplyCap.Parameters, 'chain' > - export type ReturnValue = viem_Actions.setSupplyCap.ReturnValue + export type ReturnValue = Actions.token.setSupplyCap.ReturnValue - export type ErrorType = viem_Actions.setSupplyCap.ErrorType + export type ErrorType = Actions.token.setSupplyCap.ErrorType } /** @@ -1911,11 +1914,11 @@ export declare namespace setSupplyCap { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1934,7 +1937,7 @@ export declare namespace setSupplyCap { export async function setSupplyCapSync( config: config, parameters: setSupplyCapSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -1944,23 +1947,23 @@ export async function setSupplyCapSync( connector, }) - return viem_Actions.setSupplyCapSync(client, parameters as never) + return Actions.token.setSupplyCapSync(client, parameters as never) } export declare namespace setSupplyCapSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.setSupplyCapSync.Parameters< + Actions.token.setSupplyCapSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.setSupplyCapSync.ReturnValue + export type ReturnValue = Actions.token.setSupplyCapSync.ReturnValue - export type ErrorType = viem_Actions.setSupplyCapSync.ErrorType + export type ErrorType = Actions.token.setSupplyCapSync.ErrorType } /** @@ -1969,11 +1972,11 @@ export declare namespace setSupplyCapSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -1992,7 +1995,7 @@ export declare namespace setSupplyCapSync { export async function transfer( config: config, parameters: transfer.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -2002,20 +2005,20 @@ export async function transfer( connector, }) - return viem_Actions.transfer(client, parameters as never) + return Actions.token.transfer(client, parameters as never) } export declare namespace transfer { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.transfer.Parameters, + Actions.token.transfer.Parameters, 'chain' > - export type ReturnValue = viem_Actions.transfer.ReturnValue + export type ReturnValue = Actions.token.transfer.ReturnValue - export type ErrorType = viem_Actions.transfer.ErrorType + export type ErrorType = Actions.token.transfer.ErrorType } /** @@ -2027,11 +2030,11 @@ export declare namespace transfer { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2050,7 +2053,7 @@ export declare namespace transfer { export async function transferSync( config: config, parameters: transferSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -2060,20 +2063,20 @@ export async function transferSync( connector, }) - return viem_Actions.transferSync(client, parameters as never) + return Actions.token.transferSync(client, parameters as never) } export declare namespace transferSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.transferSync.Parameters, + Actions.token.transferSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.transferSync.ReturnValue + export type ReturnValue = Actions.token.transferSync.ReturnValue - export type ErrorType = viem_Actions.transferSync.ErrorType + export type ErrorType = Actions.token.transferSync.ErrorType } /** @@ -2082,11 +2085,11 @@ export declare namespace transferSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2104,7 +2107,7 @@ export declare namespace transferSync { export async function unpause( config: config, parameters: unpause.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -2114,20 +2117,20 @@ export async function unpause( connector, }) - return viem_Actions.unpause(client, parameters as never) + return Actions.token.unpause(client, parameters as never) } export declare namespace unpause { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.unpause.Parameters, + Actions.token.unpause.Parameters, 'chain' > - export type ReturnValue = viem_Actions.unpause.ReturnValue + export type ReturnValue = Actions.token.unpause.ReturnValue - export type ErrorType = viem_Actions.unpause.ErrorType + export type ErrorType = Actions.token.unpause.ErrorType } /** @@ -2139,11 +2142,11 @@ export declare namespace unpause { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2161,7 +2164,7 @@ export declare namespace unpause { export async function unpauseSync( config: config, parameters: unpauseSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -2171,20 +2174,20 @@ export async function unpauseSync( connector, }) - return viem_Actions.unpauseSync(client, parameters as never) + return Actions.token.unpauseSync(client, parameters as never) } export declare namespace unpauseSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.unpauseSync.Parameters, + Actions.token.unpauseSync.Parameters, 'chain' > - export type ReturnValue = viem_Actions.unpauseSync.ReturnValue + export type ReturnValue = Actions.token.unpauseSync.ReturnValue - export type ErrorType = viem_Actions.unpauseSync.ErrorType + export type ErrorType = Actions.token.unpauseSync.ErrorType } /** @@ -2193,11 +2196,11 @@ export declare namespace unpauseSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2216,7 +2219,7 @@ export declare namespace unpauseSync { export async function prepareUpdateQuoteToken( config: config, parameters: prepareUpdateQuoteToken.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -2226,23 +2229,23 @@ export async function prepareUpdateQuoteToken( connector, }) - return viem_Actions.prepareUpdateQuoteToken(client, parameters as never) + return Actions.token.prepareUpdateQuoteToken(client, parameters as never) } export declare namespace prepareUpdateQuoteToken { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.prepareUpdateQuoteToken.Parameters< + Actions.token.prepareUpdateQuoteToken.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.prepareUpdateQuoteToken.ReturnValue + export type ReturnValue = Actions.token.prepareUpdateQuoteToken.ReturnValue - export type ErrorType = viem_Actions.prepareUpdateQuoteToken.ErrorType + export type ErrorType = Actions.token.prepareUpdateQuoteToken.ErrorType } /** @@ -2254,11 +2257,11 @@ export declare namespace prepareUpdateQuoteToken { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2277,7 +2280,7 @@ export declare namespace prepareUpdateQuoteToken { export async function prepareUpdateQuoteTokenSync( config: config, parameters: prepareUpdateQuoteTokenSync.Parameters, -): Promise { +): Promise { const { account, chainId, connector } = parameters const client = await getConnectorClient(config, { @@ -2287,23 +2290,24 @@ export async function prepareUpdateQuoteTokenSync( connector, }) - return viem_Actions.prepareUpdateQuoteTokenSync(client, parameters as never) + return Actions.token.prepareUpdateQuoteTokenSync(client, parameters as never) } export declare namespace prepareUpdateQuoteTokenSync { export type Parameters = ChainIdParameter & ConnectorParameter & UnionOmit< - viem_Actions.prepareUpdateQuoteTokenSync.Parameters< + Actions.token.prepareUpdateQuoteTokenSync.Parameters< config['chains'][number], Account >, 'chain' > - export type ReturnValue = viem_Actions.prepareUpdateQuoteTokenSync.ReturnValue + export type ReturnValue = + Actions.token.prepareUpdateQuoteTokenSync.ReturnValue - export type ErrorType = viem_Actions.prepareUpdateQuoteTokenSync.ErrorType + export type ErrorType = Actions.token.prepareUpdateQuoteTokenSync.ErrorType } /** @@ -2312,11 +2316,11 @@ export declare namespace prepareUpdateQuoteTokenSync { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2339,12 +2343,12 @@ export function watchAdminRole( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchAdminRole(client, rest) + return Actions.token.watchAdminRole(client, rest) } export declare namespace watchAdminRole { export type Parameters = ChainIdParameter & - viem_Actions.watchAdminRole.Parameters + Actions.token.watchAdminRole.Parameters } /** @@ -2353,11 +2357,11 @@ export declare namespace watchAdminRole { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2380,12 +2384,12 @@ export function watchApprove( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchApprove(client, rest) + return Actions.token.watchApprove(client, rest) } export declare namespace watchApprove { export type Parameters = ChainIdParameter & - viem_Actions.watchApprove.Parameters + Actions.token.watchApprove.Parameters } /** @@ -2394,11 +2398,11 @@ export declare namespace watchApprove { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2421,12 +2425,12 @@ export function watchBurn( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchBurn(client, rest) + return Actions.token.watchBurn(client, rest) } export declare namespace watchBurn { export type Parameters = ChainIdParameter & - viem_Actions.watchBurn.Parameters + Actions.token.watchBurn.Parameters } /** @@ -2435,11 +2439,11 @@ export declare namespace watchBurn { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2462,12 +2466,12 @@ export function watchCreate( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchCreate(client, rest) + return Actions.token.watchCreate(client, rest) } export declare namespace watchCreate { export type Parameters = ChainIdParameter & - viem_Actions.watchCreate.Parameters + Actions.token.watchCreate.Parameters } /** @@ -2476,11 +2480,11 @@ export declare namespace watchCreate { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2503,14 +2507,14 @@ export function watchMint( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchMint(client, rest) + return Actions.token.watchMint(client, rest) } export declare namespace watchMint { export type Parameters = ChainIdParameter & - viem_Actions.watchMint.Parameters + Actions.token.watchMint.Parameters - export type ReturnValue = viem_Actions.watchMint.ReturnValue + export type ReturnValue = Actions.token.watchMint.ReturnValue } /** @@ -2519,11 +2523,11 @@ export declare namespace watchMint { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2546,12 +2550,12 @@ export function watchRole( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchRole(client, rest) + return Actions.token.watchRole(client, rest) } export declare namespace watchRole { export type Parameters = ChainIdParameter & - viem_Actions.watchRole.Parameters + Actions.token.watchRole.Parameters } /** @@ -2560,11 +2564,11 @@ export declare namespace watchRole { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2587,12 +2591,12 @@ export function watchTransfer( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchTransfer(client, rest) + return Actions.token.watchTransfer(client, rest) } export declare namespace watchTransfer { export type Parameters = ChainIdParameter & - viem_Actions.watchTransfer.Parameters + Actions.token.watchTransfer.Parameters } /** @@ -2601,11 +2605,11 @@ export declare namespace watchTransfer { * @example * ```ts * import { createConfig, http } from '@wagmi/core' - * import { tempo } from 'tempo.ts/chains' + * import { tempo } from 'viem/chains' * import { Actions } from 'tempo.ts/wagmi' * * const config = createConfig({ - * chains: [tempo({ feeToken: '0x20c0000000000000000000000000000000000001' })], + * chains: [tempoTestnet], * transports: { * [tempo.id]: http(), * }, @@ -2631,10 +2635,10 @@ export function watchUpdateQuoteToken( ) { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) - return viem_Actions.watchUpdateQuoteToken(client, rest) + return Actions.token.watchUpdateQuoteToken(client, rest) } export declare namespace watchUpdateQuoteToken { export type Parameters = ChainIdParameter & - viem_Actions.watchUpdateQuoteToken.Parameters + Actions.token.watchUpdateQuoteToken.Parameters } diff --git a/src/wagmi/Connector.ts b/src/wagmi/Connector.ts index 0284fe39..b1bb1fef 100644 --- a/src/wagmi/Connector.ts +++ b/src/wagmi/Connector.ts @@ -1,28 +1,27 @@ +import * as idb from 'idb-keyval' import * as Address from 'ox/Address' import type * as Hex from 'ox/Hex' import * as PublicKey from 'ox/PublicKey' import { KeyAuthorization, SignatureEnvelope } from 'ox/tempo' import { createClient, + defineChain, type EIP1193Provider, getAddress, type LocalAccount, SwitchChainError, } from 'viem' import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts' +import { + Account, + WebAuthnP256, + WebCryptoP256, + walletNamespaceCompat, +} from 'viem/tempo' import { ChainNotConfiguredError, createConnector } from 'wagmi' import type { OneOf } from '../internal/types.js' -import * as Account from '../viem/Account.js' -import type * as tempo_Chain from '../viem/Chain.js' -import { normalizeValue } from '../viem/internal/utils.js' -import * as Storage from '../viem/Storage.js' -import { walletNamespaceCompat } from '../viem/Transport.js' -import * as WebAuthnP256 from '../viem/WebAuthnP256.js' -import * as WebCryptoP256 from '../viem/WebCryptoP256.js' import type * as KeyManager from './KeyManager.js' -type Chain = ReturnType> - /** * Connector for a Secp256k1 EOA. * @@ -180,10 +179,14 @@ export function dangerous_secp256k1( const transport = transports[chain.id] if (!transport) throw new ChainNotConfiguredError() + if (!account) throw new Error('account not found.') + return createClient({ account, - chain: chain as Chain, - transport: walletNamespaceCompat(transport), + chain, + transport: walletNamespaceCompat(transport, { + account, + }), }) }, async getProvider({ chainId } = {}) { @@ -221,12 +224,6 @@ export function webAuthn(options: webAuthn.Parameters) { return undefined })() - const idbStorage = Storage.idb<{ - [key: `accessKey:${string}`]: WebCryptoP256.createKeyPair.ReturnType & { - keyAuthorization: KeyAuthorization.KeyAuthorization - } - }>() - type Properties = { connect(parameters: { chainId?: number | undefined @@ -249,6 +246,9 @@ export function webAuthn(options: webAuthn.Parameters) { } type Provider = Pick type StorageItem = { + [ + key: `pendingKeyAuthorization:${string}` + ]: KeyAuthorization.KeyAuthorization 'webAuthn.activeCredential': WebAuthnP256.P256Credential 'webAuthn.lastActiveCredential': WebAuthnP256.P256Credential } @@ -329,7 +329,7 @@ export function webAuthn(options: webAuthn.Parameters) { const address = Address.fromPublicKey( PublicKey.fromHex(credential.publicKey), ) - return await idbStorage.getItem(`accessKey:${address}`) + return await idb.get(`accessKey:${address}`) })() // If the access key provisioning is not in strict mode, return the credential and key pair (if exists). @@ -414,14 +414,11 @@ export function webAuthn(options: webAuthn.Parameters) { normalizeValue(credential), ) - account = Account.fromWebAuthnP256(credential, { - storage: Storage.from(config.storage as never), - }) + account = Account.fromWebAuthnP256(credential) if (keyPair) { accessKey = Account.fromWebCryptoP256(keyPair, { access: account, - storage: Storage.from(config.storage as never), }) // If we are reconnecting, check if the access key is expired. @@ -432,7 +429,9 @@ export function webAuthn(options: webAuthn.Parameters) { keyPair.keyAuthorization.expiry < Date.now() / 1000 ) { // remove any pending key authorizations from storage. - await account?.storage.removeItem('pendingKeyAuthorization') + await config?.storage?.removeItem( + `pendingKeyAuthorization:${account.address.toLowerCase()}`, + ) const message = `Access key expired (on ${new Date(keyPair.keyAuthorization.expiry * 1000).toLocaleString()}).` accessKey = undefined @@ -452,11 +451,14 @@ export function webAuthn(options: webAuthn.Parameters) { keyAuthorization ?? (await account.signKeyAuthorization(accessKey, accessKeyOptions)) - await account.storage.setItem('pendingKeyAuthorization', keyAuth) - await idbStorage.setItem( - `accessKey:${account.address.toLowerCase()}`, - { ...keyPair, keyAuthorization: keyAuth }, + await config?.storage?.setItem( + `pendingKeyAuthorization:${account.address.toLowerCase()}`, + keyAuth, ) + await idb.set(`accessKey:${account.address.toLowerCase()}`, { + ...keyPair, + keyAuthorization: keyAuth, + }) } // If we are granting an access key and it is in strict mode, throw an error if the access key is not provisioned. } else if (accessKeyOptions?.strict) { @@ -528,7 +530,7 @@ export function webAuthn(options: webAuthn.Parameters) { const targetAccount = await (async () => { if (!accessKey) return account - const item = await idbStorage.getItem( + const item = await idb.get( `accessKey:${accessKey.address.toLowerCase()}`, ) if ( @@ -536,7 +538,9 @@ export function webAuthn(options: webAuthn.Parameters) { item.keyAuthorization.expiry < Date.now() / 1000 ) { // remove any pending key authorizations from storage. - await account?.storage.removeItem('pendingKeyAuthorization') + await config?.storage?.removeItem( + `pendingKeyAuthorization:${accessKey.address.toLowerCase()}`, + ) const message = `Access key expired (on ${new Date(item.keyAuthorization.expiry * 1000).toLocaleString()}).` @@ -552,11 +556,44 @@ export function webAuthn(options: webAuthn.Parameters) { } return accessKey })() + if (!targetAccount) throw new Error('account not found.') + + const targetChain = defineChain({ + ...chain, + async prepareTransactionRequest(args) { + const keyAuthorization = await (async () => { + { + const keyAuthorization = ( + args as { + keyAuthorization?: + | KeyAuthorization.KeyAuthorization + | undefined + } + ).keyAuthorization + if (keyAuthorization) return keyAuthorization + } + + const keyAuthorization = await config.storage?.getItem( + `pendingKeyAuthorization:${targetAccount?.address.toLowerCase()}`, + ) + await config.storage?.removeItem( + `pendingKeyAuthorization:${targetAccount?.address.toLowerCase()}`, + ) + return keyAuthorization + })() + return { + ...args, + keyAuthorization, + } + }, + }) return createClient({ account: targetAccount, - chain: chain as Chain, - transport: walletNamespaceCompat(transport), + chain: targetChain, + transport: walletNamespaceCompat(transport, { + account: targetAccount, + }), }) }, async getProvider({ chainId } = {}) { @@ -594,3 +631,24 @@ export namespace webAuthn { rpId?: string | undefined } } + +/** + * Normalizes a value into a structured-clone compatible format. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/structuredClone + */ +function normalizeValue(value: type): type { + if (Array.isArray(value)) return value.map(normalizeValue) as never + if (typeof value === 'function') return undefined as never + if (typeof value !== 'object' || value === null) return value + if (Object.getPrototypeOf(value) !== Object.prototype) + try { + return structuredClone(value) + } catch { + return undefined as never + } + + const normalized: Record = {} + for (const [k, v] of Object.entries(value)) normalized[k] = normalizeValue(v) + return normalized as never +} diff --git a/src/wagmi/Hooks/dex.test.ts b/src/wagmi/Hooks/dex.test.ts index 98f9f954..47ff1a4c 100644 --- a/src/wagmi/Hooks/dex.test.ts +++ b/src/wagmi/Hooks/dex.test.ts @@ -1,6 +1,6 @@ -import { Tick } from 'tempo.ts/viem' import { Actions, Hooks } from 'tempo.ts/wagmi' import { type Address, isAddress, parseUnits } from 'viem' +import { Tick } from 'viem/tempo' import { describe, expect, test, vi } from 'vitest' import { useConnect } from 'wagmi' import { addresses } from '../../../test/config.js' diff --git a/src/wagmi/Hooks/fee.test.ts b/src/wagmi/Hooks/fee.test.ts index 0dff8bb4..5b6265cd 100644 --- a/src/wagmi/Hooks/fee.test.ts +++ b/src/wagmi/Hooks/fee.test.ts @@ -100,7 +100,6 @@ describe('useUserToken', () => { { "account": { "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "assignKeyAuthorization": [Function], "keyType": "secp256k1", "publicKey": "0x8318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", "sign": [Function], @@ -110,11 +109,6 @@ describe('useUserToken', () => { "signTransaction": [Function], "signTypedData": [Function], "source": "root", - "storage": { - "getItem": [Function], - "removeItem": [Function], - "setItem": [Function], - }, "type": "local", }, "chainId": 1337, diff --git a/src/wagmi/Hooks/nonce.test.ts b/src/wagmi/Hooks/nonce.test.ts index 8167cfe6..dec12d3f 100644 --- a/src/wagmi/Hooks/nonce.test.ts +++ b/src/wagmi/Hooks/nonce.test.ts @@ -6,7 +6,7 @@ import { config, renderHook } from '../../../test/wagmi/config.js' import * as hooks from './nonce.js' import * as tokenHooks from './token.js' -const { useNonceKeyCount, useNonce } = hooks +const { useNonce } = hooks const account = accounts[0] const account2 = accounts[1] @@ -90,35 +90,6 @@ describe('useNonce', () => { }) }) -describe('useNonceKeyCount', () => { - test('default', async () => { - let testAccount: Address | undefined - - const { result, rerender } = await renderHook(() => - useNonceKeyCount({ account: testAccount }), - ) - - await vi.waitFor(() => result.current.fetchStatus === 'fetching') - - // Should be disabled when account is undefined - expect(result.current.data).toBeUndefined() - expect(result.current.isPending).toBe(true) - expect(result.current.isEnabled).toBe(false) - - // Set account - testAccount = account.address - rerender() - - await vi.waitFor(() => expect(result.current.isSuccess).toBeTruthy(), { - timeout: 5_000, - }) - - // Should now be enabled and have data - expect(result.current.isEnabled).toBe(true) - expect(result.current.data).toBe(0n) - }) -}) - describe('useWatchNonceIncremented', () => { test('default', async () => { const { result: connectResult } = await renderHook(() => ({ @@ -169,39 +140,3 @@ describe('useWatchNonceIncremented', () => { expect(events[1]?.newNonce).toBe(2n) }) }) - -describe('useWatchActiveKeyCountChanged', () => { - test('default', async () => { - const { result: connectResult } = await renderHook(() => ({ - connect: useConnect(), - transferSync: tokenHooks.useTransferSync(), - })) - - await connectResult.current.connect.connectAsync({ - connector: config.connectors[0]!, - }) - - const events: any[] = [] - await renderHook(() => - hooks.useWatchActiveKeyCountChanged({ - onActiveKeyCountChanged(args) { - events.push(args) - }, - }), - ) - - await connectResult.current.transferSync.mutateAsync({ - to: account2.address, - amount: 1n, - token: 1n, - nonceKey: 10n, - nonce: 0, - }) - - await vi.waitUntil(() => events.length >= 1) - - expect(events).toHaveLength(1) - expect(events[0]?.account).toBe(account.address) - expect(events[0]?.newCount).toBe(2n) - }) -}) diff --git a/src/wagmi/Hooks/nonce.ts b/src/wagmi/Hooks/nonce.ts index b964398f..20424742 100644 --- a/src/wagmi/Hooks/nonce.ts +++ b/src/wagmi/Hooks/nonce.ts @@ -6,12 +6,7 @@ import type { ConfigParameter, QueryParameter } from 'wagmi/internal' import { type UseQueryReturnType, useQuery } from 'wagmi/query' import type { ExactPartial, UnionCompute } from '../../internal/types.js' -import { - getNonce, - getNonceKeyCount, - watchActiveKeyCountChanged, - watchNonceIncremented, -} from '../Actions/nonce.js' +import { getNonce, watchNonceIncremented } from '../Actions/nonce.js' /** * Hook for getting the nonce for an account and nonce key. @@ -74,67 +69,6 @@ export declare namespace useNonce { UseQueryReturnType } -/** - * Hook for getting the number of active nonce keys for an account. - * - * @example - * ```tsx - * import { Hooks } from 'tempo.ts/wagmi' - * - * function App() { - * const { data, isLoading } = Hooks.nonce.useNonceKeyCount({ - * account: '0x...', - * }) - * - * if (isLoading) return
Loading...
- * return
Active keys: {data?.toString()}
- * } - * ``` - * - * @param parameters - Parameters. - * @returns Query result with active nonce key count. - */ -export function useNonceKeyCount< - config extends Config = ResolvedRegister['config'], - selectData = getNonceKeyCount.ReturnValue, ->(parameters: useNonceKeyCount.Parameters = {}) { - const { account, query = {} } = parameters - - const config = useConfig(parameters) - const chainId = useChainId({ config }) - - const options = getNonceKeyCount.queryOptions(config, { - ...parameters, - chainId: parameters.chainId ?? chainId, - query: undefined, - }) - const enabled = Boolean(account && (query.enabled ?? true)) - - return useQuery({ ...query, ...options, enabled }) -} - -export declare namespace useNonceKeyCount { - export type Parameters< - config extends Config = ResolvedRegister['config'], - selectData = getNonceKeyCount.ReturnValue, - > = ConfigParameter & - QueryParameter< - getNonceKeyCount.ReturnValue, - DefaultError, - selectData, - getNonceKeyCount.QueryKey - > & - ExactPartial< - Omit< - getNonceKeyCount.queryOptions.Parameters, - 'query' - > - > - - export type ReturnValue = - UseQueryReturnType -} - /** * Hook for watching nonce incremented events. * @@ -181,50 +115,3 @@ export declare namespace useWatchNonceIncremented { ConfigParameter & { enabled?: boolean | undefined } > } - -/** - * Hook for watching active key count changed events. - * - * @example - * ```tsx - * import { Hooks } from 'tempo.ts/wagmi' - * - * function App() { - * Hooks.nonce.useWatchActiveKeyCountChanged({ - * onActiveKeyCountChanged(args, log) { - * console.log('Active key count changed:', args) - * }, - * }) - * - * return
Watching for active key count changes...
- * } - * ``` - * - * @param parameters - Parameters. - */ -export function useWatchActiveKeyCountChanged< - config extends Config = ResolvedRegister['config'], ->(parameters: useWatchActiveKeyCountChanged.Parameters = {}) { - const { enabled = true, onActiveKeyCountChanged, ...rest } = parameters - - const config = useConfig({ config: parameters.config }) - const configChainId = useChainId({ config }) - const chainId = parameters.chainId ?? configChainId - - useEffect(() => { - if (!enabled) return - if (!onActiveKeyCountChanged) return - return watchActiveKeyCountChanged(config, { - ...rest, - chainId, - onActiveKeyCountChanged, - }) - }, [config, enabled, onActiveKeyCountChanged, chainId, rest]) -} - -export declare namespace useWatchActiveKeyCountChanged { - type Parameters = UnionCompute< - ExactPartial> & - ConfigParameter & { enabled?: boolean | undefined } - > -} diff --git a/src/wagmi/Hooks/policy.ts b/src/wagmi/Hooks/policy.ts index 241211e8..7558124c 100644 --- a/src/wagmi/Hooks/policy.ts +++ b/src/wagmi/Hooks/policy.ts @@ -14,8 +14,6 @@ import { import type { ExactPartial, UnionCompute } from '../../internal/types.js' import * as Actions from '../Actions/policy.js' -export type { PolicyType } from '../Actions/policy.js' - /** * Hook for creating a new policy. * diff --git a/src/wagmi/KeyManager.ts b/src/wagmi/KeyManager.ts index 231e75cb..a45dcdbd 100644 --- a/src/wagmi/KeyManager.ts +++ b/src/wagmi/KeyManager.ts @@ -1,7 +1,11 @@ import type * as Hex from 'ox/Hex' import * as Json from 'ox/Json' +import { + type CreateStorageParameters, + createStorage, + type Storage, +} from 'wagmi' import type * as Handler from '../server/Handler.js' -import * as Storage from '../viem/Storage.js' export type KeyManager = { /** Function to fetch create options for WebAuthn. */ @@ -24,8 +28,7 @@ export function from(manager: manager): manager { } /** Instantiates a key manager from a Storage instance. */ -export function fromStorage(s: Storage.Storage): KeyManager { - const storage = Storage.from(s, { key: 'webAuthn:publicKey' }) +export function fromStorage(storage: Storage): KeyManager { return from({ async getPublicKey(parameters) { const publicKey = await storage.getItem(parameters.credential.id) @@ -53,8 +56,18 @@ export function fromStorage(s: Storage.Storage): KeyManager { * * @deprecated */ -export function localStorage(options: Storage.localStorage.Options = {}) { - return fromStorage(Storage.localStorage(options)) +export function localStorage(options: localStorage.Options = {}) { + const { key = 'wagmi.keyManager' } = options + const storage = createStorage({ + ...options, + key, + storage: window.localStorage, + }) + return fromStorage(storage) +} + +export namespace localStorage { + export type Options = Omit } /** diff --git a/src/wagmi/internal/types.ts b/src/wagmi/internal/types.ts deleted file mode 100644 index feaea1cf..00000000 --- a/src/wagmi/internal/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { Config } from 'wagmi' -import type { Chain } from '../../viem/Chain.js' - -export type FeeTokenParameter< - config extends Config, - feeToken extends - | config['chains'][number]['feeToken'] - | undefined = config['chains'][number]['feeToken'], -> = { - feeToken?: - | (feeToken extends config['chains'][number]['feeToken'] - ? feeToken - : undefined) - | config['chains'][number]['feeToken'] - | undefined -} diff --git a/test/config.ts b/test/config.ts index 7bf0e923..07293c12 100644 --- a/test/config.ts +++ b/test/config.ts @@ -1,4 +1,4 @@ -import { tempoDevnet, tempoLocal, tempoTestnet } from '../src/chains.js' +import { tempoDevnet, tempoLocalnet, tempoTestnet } from 'viem/chains' export const addresses = { alphaUsd: '0x20c0000000000000000000000000000000000001', @@ -14,7 +14,7 @@ export const nodeEnv = import.meta.env.VITE_NODE_ENV || 'localnet' export const chainId = (() => { if (nodeEnv === 'testnet') return tempoTestnet.id if (nodeEnv === 'devnet') return tempoDevnet.id - return tempoLocal.id + return tempoLocalnet.id })() export const fetchOptions = { @@ -25,7 +25,7 @@ export const fetchOptions = { export const rpcUrl = (() => { const env = import.meta.env.VITE_NODE_ENV - if (env === 'testnet') return tempoTestnet({}).rpcUrls.default.http[0] - if (env === 'devnet') return tempoDevnet({}).rpcUrls.default.http[0] + if (env === 'testnet') return tempoTestnet.rpcUrls.default.http[0] + if (env === 'devnet') return tempoDevnet.rpcUrls.default.http[0] return `http://localhost:${import.meta.env.RPC_PORT ?? '8545'}/${id}` })() diff --git a/test/server/config.ts b/test/server/config.ts new file mode 100644 index 00000000..767498c3 --- /dev/null +++ b/test/server/config.ts @@ -0,0 +1,119 @@ +import { Mnemonic } from 'ox' +import { + type Chain, + type Client, + type ClientConfig, + createClient, + type HttpTransportConfig, + type Transport, + type Account as viem_Account, + http as viem_http, +} from 'viem' +import { + type Address, + english, + generateMnemonic, + type JsonRpcAccount, +} from 'viem/accounts' +import { tempoLocalnet, tempoTestnet } from 'viem/chains' +import { + // biome-ignore lint/correctness/noUnusedImports: This is needed to ensure TypeScript can reference viem/tempo types portably + type z_TokenId as _, + Account, + Actions, + Addresses, + Tick, +} from 'viem/tempo' +import { rpcUrl } from '../config.js' + +export const nodeEnv = import.meta.env.VITE_NODE_ENV || 'localnet' + +const accountsMnemonic = (() => { + if (nodeEnv === 'localnet') + return 'test test test test test test test test test test test junk' + return generateMnemonic(english) +})() + +export const accounts = Array.from({ length: 20 }, (_, i) => { + const privateKey = Mnemonic.toPrivateKey(accountsMnemonic, { + as: 'Hex', + path: Mnemonic.path({ account: i }), + }) + return Account.fromSecp256k1(privateKey) +}) as unknown as FixedArray + +export const addresses = { + alphaUsd: '0x20c0000000000000000000000000000000000001', +} as const + +export const chain = (() => { + if (nodeEnv === 'testnet') return tempoTestnet + return tempoLocalnet +})() + +export function debugOptions({ + rpcUrl, +}: { + rpcUrl: string +}): HttpTransportConfig | undefined { + if (import.meta.env.VITE_HTTP_LOG !== 'true') return undefined + return { + async onFetchRequest(_, init) { + console.log(`curl \\ +${rpcUrl} \\ +-X POST \\ +-H "Content-Type: application/json" \\ +-d '${JSON.stringify(JSON.parse(init.body as string))}'`) + }, + async onFetchResponse(response) { + console.log(`> ${JSON.stringify(await response.clone().json())}`) + }, + } +} + +export const http = (url = rpcUrl) => + viem_http(url, { + ...debugOptions({ + rpcUrl: url, + }), + }) + +export function getClient< + chain extends Chain | undefined = typeof tempoLocalnet, + accountOrAddress extends viem_Account | Address | undefined = undefined, +>( + parameters: Partial< + Pick< + ClientConfig, + 'account' | 'chain' | 'transport' + > + > = {}, +): Client< + Transport, + chain, + accountOrAddress extends Address + ? JsonRpcAccount + : accountOrAddress +> { + return createClient({ + pollingInterval: 100, + chain, + transport: http(rpcUrl), + ...parameters, + }) as never +} + +export declare namespace fundAddress { + export type Parameters = { + /** Account to fund. */ + address: Address + } +} + +type FixedArray< + type, + count extends number, + result extends readonly type[] = [], +> = result['length'] extends count + ? result + : FixedArray diff --git a/test/server/setup.ts b/test/server/setup.ts index 575efe75..05781af8 100644 --- a/test/server/setup.ts +++ b/test/server/setup.ts @@ -1,11 +1,11 @@ +import { Actions } from 'viem/tempo' import { afterAll, beforeAll } from 'vitest' -import { Actions } from '../../src/viem/index.js' -import { nodeEnv, rpcUrl } from '../config.js' -import { accounts, client } from '../viem/config.js' +import { rpcUrl } from '../config.js' +import { accounts, getClient, nodeEnv } from './config.js' beforeAll(async () => { if (nodeEnv === 'localnet') return - await Actions.faucet.fundSync(client, { + await Actions.faucet.fundSync(getClient(), { account: accounts[0].address, }) }) diff --git a/test/viem-attest/setup.global.ts b/test/viem-attest/setup.global.ts deleted file mode 100644 index a8d5a1d1..00000000 --- a/test/viem-attest/setup.global.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { join } from 'node:path' -import { setup } from '@ark/attest' - -export default () => - setup({ - formatCmd: 'pnpm check', - tsconfig: join(import.meta.dirname, '../../src/tsconfig.json'), - }) diff --git a/test/viem/config.ts b/test/viem/config.ts index 026f49a0..dffc3e39 100644 --- a/test/viem/config.ts +++ b/test/viem/config.ts @@ -1,18 +1,15 @@ import type { FixedArray } from '@wagmi/core/internal' import * as Mnemonic from 'ox/Mnemonic' -import { - Actions, - Addresses, - Chain, - Tick, - Account as tempo_Account, -} from 'tempo.ts/viem' +// biome-ignore lint/correctness/noUnusedImports: imported for inference +import { TokenId as _ } from 'ox/tempo' import { type Account, type Address, + type Chain, type Client, type ClientConfig, createClient, + defineChain, type HttpTransportConfig, parseUnits, type Transport, @@ -20,8 +17,8 @@ import { } from 'viem' import { english, generateMnemonic } from 'viem/accounts' import { sendTransactionSync } from 'viem/actions' -import { tempoDevnet, tempoTestnet } from '../../src/chains.js' -import { transferSync } from '../../src/viem/Actions/token.js' +import { tempoDevnet, tempoLocalnet, tempoTestnet } from 'viem/chains' +import { Actions, Addresses, Tick, Account as tempo_Account } from 'viem/tempo' import { addresses, fetchOptions, nodeEnv, rpcUrl } from '../config.js' const accountsMnemonic = (() => { @@ -38,14 +35,8 @@ export const accounts = Array.from({ length: 20 }, (_, i) => { return tempo_Account.fromSecp256k1(privateKey) }) as unknown as FixedArray -export const tempoTest = Chain.define({ - id: 1337, - name: 'Tempo', - nativeCurrency: { - name: 'USD', - symbol: 'USD', - decimals: 6, - }, +export const tempoTest = defineChain({ + ...tempoLocalnet, rpcUrls: { default: { http: [rpcUrl], @@ -59,7 +50,7 @@ export const chainFn = (() => { if (env === 'devnet') return tempoDevnet return tempoTest })() -export const chain = chainFn({ feeToken: 1n }) +export const chain = chainFn.extend({ feeToken: 1n }) export function debugOptions({ rpcUrl, @@ -113,13 +104,13 @@ export const clientWithAccount = getClient({ }) export async function fundAddress( - client: Client>, + client: Client, parameters: fundAddress.Parameters, ) { const { address } = parameters const account = accounts.at(0)! if (account.address === address) return - await transferSync(client, { + await Actions.token.transferSync(client, { account, amount: parseUnits('10000', 6), to: address, @@ -135,11 +126,7 @@ export declare namespace fundAddress { } export async function setupToken( - client: Client< - Transport, - Chain.Chain, - Account - >, + client: Client, parameters: Partial< Awaited> > = {}, @@ -167,11 +154,7 @@ export async function setupToken( } export async function setupPoolWithLiquidity( - client: Client< - Transport, - Chain.Chain, - Account - >, + client: Client, ) { // Create a new token for testing const { token } = await Actions.token.createSync(client, { diff --git a/test/viem/setup.global.ts b/test/viem/setup.global.ts deleted file mode 100644 index 9db5000a..00000000 --- a/test/viem/setup.global.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { nodeEnv } from '../config.js' -import { setupServer } from '../prool.js' - -export default async function () { - if (nodeEnv !== 'localnet') return undefined - return await setupServer({ port: 8545 }) -} diff --git a/test/viem/setup.ts b/test/viem/setup.ts deleted file mode 100644 index 652f89f1..00000000 --- a/test/viem/setup.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { setTimeout } from 'node:timers/promises' -import { afterAll, beforeAll } from 'vitest' -import { Actions } from '../../src/viem/index.js' -import { nodeEnv, rpcUrl } from '../config.js' -import { accounts, client } from './config.js' - -beforeAll(async () => { - if (nodeEnv === 'localnet') return - await Actions.faucet.fundSync(client, { - account: accounts[0].address, - }) - // TODO: remove once testnet load balancing is fixed. - await setTimeout(2000) -}) - -afterAll(async () => { - if (nodeEnv !== 'localnet') return - await fetch(`${rpcUrl}/stop`) -}) diff --git a/test/wagmi/config.ts b/test/wagmi/config.ts index 3201fbe5..d657cbcc 100644 --- a/test/wagmi/config.ts +++ b/test/wagmi/config.ts @@ -1,7 +1,6 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { connect, getAccount, getConnectorClient } from '@wagmi/core' -// These imports ensure TypeScript can reference ox/tempo types portably -// biome-ignore lint/correctness/noUnusedImports: _ +// biome-ignore lint/correctness/noUnusedImports: imported for inference import type { KeyAuthorization as _, SignatureEnvelope as __, @@ -10,6 +9,8 @@ import type { } from 'ox/tempo' import * as React from 'react' import { http } from 'viem' +// biome-ignore lint/correctness/noUnusedImports: imported for inference +import * as _viem from 'viem/tempo' import { type RenderHookOptions, type RenderHookResult, diff --git a/test/wagmi/setup.ts b/test/wagmi/setup.ts index 2c6eff98..5531d244 100644 --- a/test/wagmi/setup.ts +++ b/test/wagmi/setup.ts @@ -1,6 +1,6 @@ import { disconnect } from '@wagmi/core' +import { Actions } from 'viem/tempo' import { afterAll, beforeAll, beforeEach, vi } from 'vitest' -import { Actions } from '../../src/viem/index.js' import { nodeEnv, rpcUrl } from '../config.js' import { accounts, client } from '../viem/config.js' import { config } from '../wagmi/config.js' diff --git a/vitest.config.ts b/vitest.config.ts index 7eadf067..df89f4d9 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -15,14 +15,6 @@ export default defineConfig({ testTimeout: 30_000, reporters: process.env.CI ? ['tree'] : [], projects: [ - { - extends: true, - test: { - name: 'prool', - root: './src/prool', - sequence: { groupOrder: 1 }, - }, - }, { extends: true, test: { @@ -38,38 +30,6 @@ export default defineConfig({ setupFiles: [join(import.meta.dirname, './test/server/setup.ts')], }, }, - { - extends: true, - test: { - env: { - RPC_PORT: '8545', - }, - globalSetup: [ - join(import.meta.dirname, './test/viem/setup.global.ts'), - ], - name: 'viem', - root: './src/viem', - environment: 'node', - include: ['**/*.{test,spec}.?(c|m)[jt]s?(x)', '**/*.test-d.ts'], - typecheck: { - enabled: true, - }, - sequence: { groupOrder: 3 }, - setupFiles: [join(import.meta.dirname, './test/viem/setup.ts')], - }, - }, - // { - // extends: true, - // test: { - // globalSetup: [ - // join(import.meta.dirname, './test/viem-attest/setup.global.ts'), - // ], - // name: 'attest/viem', - // root: './src/viem', - // environment: 'node', - // include: ['**/*.bench-d.ts'], - // }, - // }, { extends: true, plugins: [react()], From d55d01c0d2d534d9a1915fc001e3285c7e820ef7 Mon Sep 17 00:00:00 2001 From: jxom <7336481+jxom@users.noreply.github.com> Date: Mon, 22 Dec 2025 10:13:12 +1100 Subject: [PATCH 2/2] chore: up --- .github/workflows/verify.yml | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 4acd34c4..4c9fed34 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -67,32 +67,3 @@ jobs: CI: true VITE_NODE_TAG: ${{ matrix.tag }} VITE_RPC_CREDENTIALS: ${{ secrets.VITE_RPC_CREDENTIALS }} - - test-deployed: - name: 'Test Runtime (env: ${{ matrix.node-env }}, e2e)' - runs-on: ubuntu-latest - timeout-minutes: 30 - strategy: - matrix: - node-env: - - testnet - steps: - - name: Clone repository - uses: actions/checkout@v4 - with: - submodules: 'recursive' - token: ${{ secrets.GH_PAT }} - - - name: Install dependencies - uses: ./.github/actions/install-dependencies - - - name: Run tests - uses: nick-fields/retry@v3 - with: - timeout_minutes: 10 - max_attempts: 3 - command: pnpm test e2e --bail=1 - env: - CI: true - VITE_NODE_ENV: ${{ matrix.node-env }} - VITE_RPC_CREDENTIALS: ${{ secrets.VITE_RPC_CREDENTIALS }} \ No newline at end of file