diff --git a/apps/desktop/package.json b/apps/desktop/package.json
index ffe0a15..100a448 100644
--- a/apps/desktop/package.json
+++ b/apps/desktop/package.json
@@ -16,7 +16,8 @@
"build:native": "swiftc -O -o src/bun/native/biometric-helper src/bun/native/biometric-helper.swift"
},
"dependencies": {
- "@alchemy/wallet-apis": "^5.0.0-beta.28",
+ "@alchemy/common": "^5.0.0",
+ "@alchemy/wallet-apis": "^5.0.0",
"@koins/utils": "workspace:*",
"drizzle-orm": "^1.0.0-beta.22",
"electrobun": "^1.18.1",
diff --git a/apps/desktop/src/bun/rpc/evm/index.ts b/apps/desktop/src/bun/rpc/evm/index.ts
index 3d41ecd..edd7f0a 100644
--- a/apps/desktop/src/bun/rpc/evm/index.ts
+++ b/apps/desktop/src/bun/rpc/evm/index.ts
@@ -10,7 +10,11 @@ import { syncTransactionHistory } from '../../lib/sync'
import { eq, and } from 'drizzle-orm'
import { db } from '../../lib/db'
import { getClient } from '../../lib/viem'
-import { formatGwei } from 'viem'
+import { formatGwei, parseEther, parseUnits, encodeFunctionData, createWalletClient } from 'viem'
+import { mnemonicToAccount } from 'viem/accounts'
+import { getChain } from '../../lib/viem/getChain'
+import { getChainID } from '../../lib/alchemy/network'
+import { alchemyTransport } from '@alchemy/common'
import { sqlite } from '../../lib/sqlite'
import { txHistory, evmWallets } from '../../lib/db/schema'
import type {
@@ -566,5 +570,64 @@ export function createEvmHandlers(
db.delete(evmWallets).where(eq(evmWallets.id, id)).run()
console.log('[rpc] evmDeleteWallet complete')
},
+ evmSendTransfer: async ({
+ seed,
+ to,
+ amount,
+ chainid,
+ contractAddress,
+ tokenDecimals,
+ }: {
+ seed: string
+ to: string
+ amount: string
+ chainid: string
+ contractAddress?: string
+ tokenDecimals?: number
+ }) => {
+ const key = await Bun.secrets.get({
+ service: 'koins',
+ name: 'alchemy_key',
+ })
+ if (!key) throw new Error('API key not set')
+ const account = mnemonicToAccount(seed)
+ const id = getChainID(chainid)
+ if (!id) throw new Error('Unsupported chain')
+ const chain = getChain(id)
+ const walletClient = createWalletClient({
+ account,
+ chain,
+ transport: alchemyTransport({ apiKey: key }),
+ })
+ if (contractAddress && tokenDecimals !== undefined) {
+ const erc20Abi = [
+ {
+ name: 'transfer',
+ type: 'function',
+ inputs: [
+ { name: 'to', type: 'address' },
+ { name: 'amount', type: 'uint256' },
+ ],
+ outputs: [{ name: '', type: 'bool' }],
+ },
+ ] as const
+ const data = encodeFunctionData({
+ abi: erc20Abi,
+ functionName: 'transfer',
+ args: [to as `0x${string}`, parseUnits(amount, tokenDecimals)],
+ })
+ const hash = await walletClient.sendTransaction({
+ to: contractAddress as `0x${string}`,
+ data,
+ value: 0n,
+ })
+ return hash
+ }
+ const hash = await walletClient.sendTransaction({
+ to: to as `0x${string}`,
+ value: parseEther(amount),
+ })
+ return hash
+ },
}
}
diff --git a/apps/desktop/src/lib/components/EvmDashboard.svelte b/apps/desktop/src/lib/components/EvmDashboard.svelte
index af734a9..d995632 100644
--- a/apps/desktop/src/lib/components/EvmDashboard.svelte
+++ b/apps/desktop/src/lib/components/EvmDashboard.svelte
@@ -487,6 +487,11 @@
{/if}
+