diff --git a/bun.lock b/bun.lock index b6a14e3c7..c1f1a745a 100644 --- a/bun.lock +++ b/bun.lock @@ -164,6 +164,7 @@ "@swapkit/toolboxes": "workspace:*", "@trezor/connect-web": "9.4.7", "@walletconnect/modal-sign-html": "2.7.0", + "bitcoinjs-lib": "6.1.7", "blakejs": "1.2.1", "cosmjs-types": "0.9.0", "sats-connect": "3.2.0", diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index cea67bdae..eb49b8f42 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -91,10 +91,15 @@ export function SwapKit< return plugin; } - function addChain(connectWallet: ChainWallet) { + function addChain( + connectWallet: Omit, "balance"> & { balance?: AssetValue[] }, + ) { const currentWallet = getWallet(connectWallet.chain); - connectedWallets[connectWallet.chain] = { ...currentWallet, ...connectWallet }; + const balance = connectWallet.balance || + currentWallet.balance || [AssetValue.from({ chain: connectWallet.chain })]; + + connectedWallets[connectWallet.chain] = { ...currentWallet, ...connectWallet, balance }; } // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: @@ -153,7 +158,7 @@ export function SwapKit< * @Public */ function getWallet(chain: T) { - return connectedWallets[chain]; + return connectedWallets[chain] || {}; } function getAllWallets() { diff --git a/packages/helpers/src/api/swapkitApi/endpoints.ts b/packages/helpers/src/api/swapkitApi/endpoints.ts index aeebe10d5..a19a62b82 100644 --- a/packages/helpers/src/api/swapkitApi/endpoints.ts +++ b/packages/helpers/src/api/swapkitApi/endpoints.ts @@ -1,4 +1,3 @@ -import { createHash } from "crypto"; import { ProviderName, RequestClient, SKConfig, SwapKitError, warnOnce } from "@swapkit/helpers"; import { @@ -54,6 +53,8 @@ export const computeHash = ( ? JSON.stringify(hashParams.payload) : `${hashParams.url}${swapKit}`; + const { createHash } = require("crypto"); + return createHash("sha256").update(data, "utf8").digest("hex"); }; diff --git a/packages/helpers/src/types/commonTypes.ts b/packages/helpers/src/types/commonTypes.ts index 2317a15f2..8271f0ff6 100644 --- a/packages/helpers/src/types/commonTypes.ts +++ b/packages/helpers/src/types/commonTypes.ts @@ -2,7 +2,7 @@ import type { Chain } from "./chains"; import type { ChainWallet, CryptoChain } from "./wallet"; export type AddChainType = ( - params: ChainWallet & M, + params: Omit, "balance"> & M, ) => void; export type Witness = { diff --git a/packages/toolboxes/src/utxo/index.ts b/packages/toolboxes/src/utxo/index.ts index 1574f6b5b..2d712e716 100644 --- a/packages/toolboxes/src/utxo/index.ts +++ b/packages/toolboxes/src/utxo/index.ts @@ -1,5 +1,3 @@ -export { type Network, networks, Psbt, Transaction } from "bitcoinjs-lib"; - /** * Package */ diff --git a/packages/wallets/package.json b/packages/wallets/package.json index 500cb36d9..bd323d110 100644 --- a/packages/wallets/package.json +++ b/packages/wallets/package.json @@ -27,6 +27,7 @@ "@swapkit/toolboxes": "workspace:*", "@trezor/connect-web": "9.4.7", "@walletconnect/modal-sign-html": "2.7.0", + "bitcoinjs-lib": "6.1.7", "blakejs": "1.2.1", "cosmjs-types": "0.9.0", "sats-connect": "3.2.0" diff --git a/packages/wallets/src/bitget/bitgetWallet.ts b/packages/wallets/src/bitget/bitgetWallet.ts index aaa69da3b..8c71eff02 100644 --- a/packages/wallets/src/bitget/bitgetWallet.ts +++ b/packages/wallets/src/bitget/bitgetWallet.ts @@ -21,7 +21,7 @@ export const bitgetWallet = createWallet({ filteredChains.map(async (chain) => { const walletMethods = await getWalletMethods(chain); - addChain({ ...walletMethods, chain, balance: [], walletType }); + addChain({ ...walletMethods, chain, walletType }); }), ); diff --git a/packages/wallets/src/bitget/helpers.ts b/packages/wallets/src/bitget/helpers.ts index 23f72df60..b1666ee80 100644 --- a/packages/wallets/src/bitget/helpers.ts +++ b/packages/wallets/src/bitget/helpers.ts @@ -10,7 +10,8 @@ import { switchEVMWalletNetwork, } from "@swapkit/helpers"; import type { TransferParams } from "@swapkit/toolboxes/cosmos"; -import type { Psbt, UTXOTransferParams } from "@swapkit/toolboxes/utxo"; +import type { UTXOTransferParams } from "@swapkit/toolboxes/utxo"; +import type { Psbt } from "bitcoinjs-lib"; import type { Eip1193Provider } from "ethers"; function cosmosTransfer() { @@ -76,7 +77,8 @@ export async function getWalletMethods(chain: Chain) { } const { unisat: wallet } = bitget; - const { Psbt, BTCToolbox } = await import("@swapkit/toolboxes/utxo"); + const { Psbt } = await import("bitcoinjs-lib"); + const { BTCToolbox } = await import("@swapkit/toolboxes/utxo"); const [address] = await wallet.requestAccounts(); const toolbox = BTCToolbox(); diff --git a/packages/wallets/src/coinbase/index.ts b/packages/wallets/src/coinbase/index.ts index c4b09e5c2..2a4481956 100644 --- a/packages/wallets/src/coinbase/index.ts +++ b/packages/wallets/src/coinbase/index.ts @@ -41,7 +41,7 @@ export const coinbaseWallet = createWallet({ filteredChains.map(async (chain) => { const walletMethods = await getWalletMethods({ chain, coinbaseSdk }); - addChain({ ...walletMethods, balance: [], chain, walletType }); + addChain({ ...walletMethods, chain, walletType }); }), ); diff --git a/packages/wallets/src/ctrl/ctrlWallet.ts b/packages/wallets/src/ctrl/ctrlWallet.ts index 1332222a2..7492902ac 100644 --- a/packages/wallets/src/ctrl/ctrlWallet.ts +++ b/packages/wallets/src/ctrl/ctrlWallet.ts @@ -47,7 +47,7 @@ export const ctrlWallet = createWallet({ const address = await getCtrlAddress(chain); const walletMethods = await getWalletMethods(chain); - addChain({ ...walletMethods, address, balance: [], chain, walletType }); + addChain({ ...walletMethods, address, chain, walletType }); }); await Promise.all(promises); diff --git a/packages/wallets/src/evm-extensions/index.ts b/packages/wallets/src/evm-extensions/index.ts index b59b3f890..1a04e0ec5 100644 --- a/packages/wallets/src/evm-extensions/index.ts +++ b/packages/wallets/src/evm-extensions/index.ts @@ -103,14 +103,7 @@ export const evmWallet = createWallet({ const getBalance = async (potentialScamFilter = true) => walletMethods.getBalance(address, potentialScamFilter, getProvider(chain)); - addChain({ - ...walletMethods, - address, - balance: [], - chain, - getBalance, - walletType, - }); + addChain({ ...walletMethods, address, chain, getBalance, walletType }); return; } @@ -131,15 +124,7 @@ export const evmWallet = createWallet({ const disconnect = () => web3provider.send("wallet_revokePermissions", [{ eth_accounts: {} }]); - addChain({ - ...walletMethods, - address, - balance: [], - chain, - disconnect, - getBalance, - walletType, - }); + addChain({ ...walletMethods, address, chain, disconnect, getBalance, walletType }); }), ); diff --git a/packages/wallets/src/exodus/index.ts b/packages/wallets/src/exodus/index.ts index 5a30d9a03..612cf02af 100644 --- a/packages/wallets/src/exodus/index.ts +++ b/packages/wallets/src/exodus/index.ts @@ -10,7 +10,7 @@ import { switchEVMWalletNetwork, } from "@swapkit/helpers"; import type { UTXOTransferParams } from "@swapkit/toolboxes/utxo"; -import type { Psbt } from "@swapkit/toolboxes/utxo"; +import type { Psbt } from "bitcoinjs-lib"; import type { BrowserProvider, Eip1193Provider } from "ethers"; import { AddressPurpose, @@ -35,7 +35,8 @@ async function getWalletMethods({ }) { switch (chain) { case Chain.Bitcoin: { - const { BTCToolbox, Psbt } = await import("@swapkit/toolboxes/utxo"); + const { Psbt } = await import("bitcoinjs-lib"); + const { BTCToolbox } = await import("@swapkit/toolboxes/utxo"); const toolbox = BTCToolbox(); let address = ""; @@ -174,7 +175,6 @@ export const exodusWallet = createWallet({ chain, address, getBalance, - balance: [], walletType: WalletOption.EXODUS, }); }), diff --git a/packages/wallets/src/keepkey-bex/index.ts b/packages/wallets/src/keepkey-bex/index.ts index 3296a41b1..847b3afe9 100644 --- a/packages/wallets/src/keepkey-bex/index.ts +++ b/packages/wallets/src/keepkey-bex/index.ts @@ -49,7 +49,7 @@ export const keepkeyBexWallet = createWallet({ const address = await getKEEPKEYAddress(chain); const walletMethods = await getWalletMethods(chain); - addChain({ ...walletMethods, address, balance: [], chain, walletType }); + addChain({ ...walletMethods, address, chain, walletType }); }), ); diff --git a/packages/wallets/src/keepkey/chains/utxo.ts b/packages/wallets/src/keepkey/chains/utxo.ts index 8080141c6..34c245902 100644 --- a/packages/wallets/src/keepkey/chains/utxo.ts +++ b/packages/wallets/src/keepkey/chains/utxo.ts @@ -6,7 +6,8 @@ import { type UTXOChain, derivationPathToString, } from "@swapkit/helpers"; -import type { BCHToolbox, Psbt, UTXOToolbox, UTXOTransferParams } from "@swapkit/toolboxes/utxo"; +import type { BCHToolbox, UTXOToolbox, UTXOTransferParams } from "@swapkit/toolboxes/utxo"; +import type { Psbt } from "bitcoinjs-lib"; import { ChainToKeepKeyName, bip32ToAddressNList } from "../coins"; diff --git a/packages/wallets/src/keepkey/index.ts b/packages/wallets/src/keepkey/index.ts index b069b1c0e..20c938eb5 100644 --- a/packages/wallets/src/keepkey/index.ts +++ b/packages/wallets/src/keepkey/index.ts @@ -61,12 +61,7 @@ export const keepkeyWallet = createWallet({ sdk: keepKeySdk, }); - addChain({ - ...walletMethods, - balance: [], - chain, - walletType: WalletOption.KEEPKEY, - }); + addChain({ ...walletMethods, chain, walletType: WalletOption.KEEPKEY }); }), ); return true; diff --git a/packages/wallets/src/keplr/index.ts b/packages/wallets/src/keplr/index.ts index 64bb6a0df..825f44be4 100644 --- a/packages/wallets/src/keplr/index.ts +++ b/packages/wallets/src/keplr/index.ts @@ -90,7 +90,6 @@ export const keplrWallet = createWallet({ chain, transfer, address, - balance: [], walletType, }); }), diff --git a/packages/wallets/src/keystore/index.ts b/packages/wallets/src/keystore/index.ts index 9d04dc3a3..e3538660a 100644 --- a/packages/wallets/src/keystore/index.ts +++ b/packages/wallets/src/keystore/index.ts @@ -16,11 +16,11 @@ import { } from "@swapkit/helpers"; import type { DepositParam, TransferParams } from "@swapkit/toolboxes/cosmos"; import type { - Psbt, TransactionType, UTXOTransferParams, UTXOWalletTransferParams, } from "@swapkit/toolboxes/utxo"; +import type { Psbt } from "bitcoinjs-lib"; import { getWalletSupportedChains } from "../helpers"; type Params = { @@ -217,13 +217,7 @@ export const keystoreWallet = createWallet({ phrase, }); - addChain({ - ...walletMethods, - address, - balance: [], - chain, - walletType: WalletOption.KEYSTORE, - }); + addChain({ ...walletMethods, address, chain, walletType: WalletOption.KEYSTORE }); }), ); diff --git a/packages/wallets/src/ledger/clients/utxo.ts b/packages/wallets/src/ledger/clients/utxo.ts index 4c03dbd42..16f9d69a1 100644 --- a/packages/wallets/src/ledger/clients/utxo.ts +++ b/packages/wallets/src/ledger/clients/utxo.ts @@ -6,7 +6,8 @@ import { derivationPathToString, getWalletFormatFor, } from "@swapkit/helpers"; -import type { Psbt, UTXOType } from "@swapkit/toolboxes/utxo"; +import type { UTXOType } from "@swapkit/toolboxes/utxo"; +import type { Psbt } from "bitcoinjs-lib"; import { getLedgerTransport } from "../helpers/getLedgerTransport"; @@ -21,7 +22,7 @@ const signUTXOTransaction = async ( { psbt, inputUtxos, btcApp, derivationPath }: Params, options?: Partial, ) => { - const { Transaction } = await import("@swapkit/toolboxes/utxo"); + const { Transaction } = await import("bitcoinjs-lib"); const inputs = inputUtxos.map((item) => { const utxoTx = Transaction.fromHex(item.txHex || ""); diff --git a/packages/wallets/src/ledger/index.ts b/packages/wallets/src/ledger/index.ts index d4825e912..1e687936a 100644 --- a/packages/wallets/src/ledger/index.ts +++ b/packages/wallets/src/ledger/index.ts @@ -42,7 +42,7 @@ export const ledgerWallet = createWallet({ const walletMethods = await getWalletMethods({ chain, derivationPath }); - addChain({ ...walletMethods, chain, balance: [], walletType: WalletOption.LEDGER }); + addChain({ ...walletMethods, chain, walletType: WalletOption.LEDGER }); return true; }, diff --git a/packages/wallets/src/ledger/ledgerLive.ts b/packages/wallets/src/ledger/ledgerLive.ts index c72d5939a..ff26fb60c 100644 --- a/packages/wallets/src/ledger/ledgerLive.ts +++ b/packages/wallets/src/ledger/ledgerLive.ts @@ -421,7 +421,7 @@ export const ledgerLiveWallet = createWallet({ const toolbox = await getLedgerLiveWallet({ chain, ledgerLiveAccount }); - addChain({ ...toolbox, chain, balance: [], walletType }); + addChain({ ...toolbox, chain, walletType }); return true; }, diff --git a/packages/wallets/src/okx/helpers.ts b/packages/wallets/src/okx/helpers.ts index 58d81a0b3..6fb6eeb99 100644 --- a/packages/wallets/src/okx/helpers.ts +++ b/packages/wallets/src/okx/helpers.ts @@ -7,7 +7,7 @@ import { switchEVMWalletNetwork, } from "@swapkit/helpers"; import type { GaiaToolbox } from "@swapkit/toolboxes/cosmos"; -import type { BTCToolbox, Psbt, UTXOTransferParams } from "@swapkit/toolboxes/utxo"; +import type { BTCToolbox, UTXOTransferParams } from "@swapkit/toolboxes/utxo"; import type { Eip1193Provider } from "ethers"; const cosmosTransfer = @@ -95,13 +95,14 @@ export async function getWalletMethods( if (!(window.okxwallet && "bitcoin" in window.okxwallet)) { throw new Error("No bitcoin okxwallet found"); } - const { Psbt, BTCToolbox } = await import("@swapkit/toolboxes/utxo"); + const { Psbt } = await import("bitcoinjs-lib"); + const { BTCToolbox } = await import("@swapkit/toolboxes/utxo"); const { bitcoin: wallet } = window.okxwallet; const address = (await wallet.connect()).address; const toolbox = BTCToolbox(); - const signTransaction = async (psbt: Psbt) => { + const signTransaction = async (psbt: InstanceType) => { const signedPsbt = await wallet.signPsbt(psbt.toHex(), { from: address, type: "list" }); return Psbt.fromHex(signedPsbt); diff --git a/packages/wallets/src/okx/index.ts b/packages/wallets/src/okx/index.ts index 544599fe9..7494b0c5d 100644 --- a/packages/wallets/src/okx/index.ts +++ b/packages/wallets/src/okx/index.ts @@ -28,7 +28,7 @@ export const okxWallet = createWallet({ filteredChains.map(async (chain) => { const walletMethods = await getWalletMethods(chain); - addChain({ ...walletMethods, chain, balance: [], walletType }); + addChain({ ...walletMethods, chain, walletType }); }), ); diff --git a/packages/wallets/src/phantom/index.ts b/packages/wallets/src/phantom/index.ts index 7066d8c6f..dbb38b710 100644 --- a/packages/wallets/src/phantom/index.ts +++ b/packages/wallets/src/phantom/index.ts @@ -23,7 +23,7 @@ export const phantomWallet = createWallet({ filteredChains.map(async (chain) => { const { address, ...methods } = await getWalletMethods(chain); - addChain({ ...methods, chain, address, walletType, balance: [] }); + addChain({ ...methods, chain, address, walletType }); }), ); diff --git a/packages/wallets/src/polkadotjs/index.ts b/packages/wallets/src/polkadotjs/index.ts index 08db9e46b..81b2c616a 100644 --- a/packages/wallets/src/polkadotjs/index.ts +++ b/packages/wallets/src/polkadotjs/index.ts @@ -20,7 +20,7 @@ export const polkadotWallet = createWallet({ filteredChains.map(async (chain) => { const { address, ...walletMethods } = await getWalletMethods(chain); - addChain({ ...walletMethods, chain, address, walletType, balance: [] }); + addChain({ ...walletMethods, chain, address, walletType }); }), ); diff --git a/packages/wallets/src/radix/index.ts b/packages/wallets/src/radix/index.ts index 5697ef049..705d5e384 100644 --- a/packages/wallets/src/radix/index.ts +++ b/packages/wallets/src/radix/index.ts @@ -33,7 +33,7 @@ export const radixWallet = createWallet({ filteredChains.map(async (chain) => { const walletMethods = await getWalletMethods(); - addChain({ ...walletMethods, chain, balance: [], walletType }); + addChain({ ...walletMethods, chain, walletType }); }), ); diff --git a/packages/wallets/src/talisman/index.ts b/packages/wallets/src/talisman/index.ts index d914f3917..4ee31d51a 100644 --- a/packages/wallets/src/talisman/index.ts +++ b/packages/wallets/src/talisman/index.ts @@ -35,7 +35,7 @@ export const talismanWallet = createWallet({ filteredChains.map(async (chain) => { const { address, ...walletMethods } = await getWalletMethods(chain); - addChain({ ...walletMethods, address, balance: [], chain, walletType }); + addChain({ ...walletMethods, address, chain, walletType }); }), ); diff --git a/packages/wallets/src/trezor/index.ts b/packages/wallets/src/trezor/index.ts index f628fe68d..96cbb0894 100644 --- a/packages/wallets/src/trezor/index.ts +++ b/packages/wallets/src/trezor/index.ts @@ -9,7 +9,8 @@ import { derivationPathToString, filterSupportedChains, } from "@swapkit/helpers"; -import type { Psbt, UTXOTransferParams, UTXOType } from "@swapkit/toolboxes/utxo"; +import type { UTXOTransferParams, UTXOType } from "@swapkit/toolboxes/utxo"; +import type { Psbt } from "bitcoinjs-lib"; import { getWalletSupportedChains } from "../helpers"; function getScriptType(derivationPath: DerivationPathArray) { @@ -238,7 +239,7 @@ export const trezorWallet = createWallet({ const { address, walletMethods } = await getToolbox({ chain, derivationPath }); - addChain({ ...walletMethods, address, balance: [], chain, walletType }); + addChain({ ...walletMethods, address, chain, walletType }); return true; }, diff --git a/packages/wallets/src/walletconnect/index.ts b/packages/wallets/src/walletconnect/index.ts index 00dcf24cb..4cede9be5 100644 --- a/packages/wallets/src/walletconnect/index.ts +++ b/packages/wallets/src/walletconnect/index.ts @@ -93,7 +93,6 @@ export const walletconnectWallet = createWallet({ addChain({ ...toolbox, address, - balance: [], chain, disconnect: walletconnect.disconnect, walletType: WalletOption.WALLETCONNECT, diff --git a/playgrounds/nextjs/package.json b/playgrounds/nextjs/package.json index 65f82b094..45a2e6380 100644 --- a/playgrounds/nextjs/package.json +++ b/playgrounds/nextjs/package.json @@ -7,8 +7,7 @@ "clean": "rm -rf .next node_modules", "build-playground": "next build", "start": "next start", - "lint": "biome check --write ./src", - "type-check": "tsc --noEmit" + "lint": "biome check --write ./src" }, "dependencies": { "@hookform/resolvers": "4.1.2", diff --git a/playgrounds/vite/package.json b/playgrounds/vite/package.json index fc2f01f75..3efc309ee 100644 --- a/playgrounds/vite/package.json +++ b/playgrounds/vite/package.json @@ -35,7 +35,6 @@ "visualise": "VISUALISE=true bun build-playground", "dev": "vite", "lint": "biome check --write ./src", - "type-check": "tsc --noEmit", "preview-playground": "vite preview" }, "version": "0.0.0" diff --git a/playgrounds/vite/src/WalletPicker.tsx b/playgrounds/vite/src/WalletPicker.tsx index 57378cb5d..e2b467c35 100644 --- a/playgrounds/vite/src/WalletPicker.tsx +++ b/playgrounds/vite/src/WalletPicker.tsx @@ -148,6 +148,7 @@ export const availableChainsByWallet = { export const WalletPicker = ({ skClient, setWallet, setPhrase }: Props) => { const [loading, setLoading] = useState(false); + const [balanceLoading, setBalanceLoading] = useState(false); const [chains, setChains] = useState([]); const connectWallet = useCallback( @@ -221,6 +222,22 @@ export const WalletPicker = ({ skClient, setWallet, setPhrase }: Props) => { [chains, skClient], ); + const handleBalanceUpdate = useCallback(async () => { + if (!skClient) return alert("client is not ready"); + setBalanceLoading(true); + try { + const walletDataArray = await Promise.all( + chains.map((chain) => skClient.getWalletWithBalance(chain, true)), + ); + setWallet(walletDataArray.filter(Boolean)); + } catch (e) { + console.error(e); + alert(e); + } finally { + setBalanceLoading(false); + } + }, [chains, skClient, setWallet]); + const handleKeystoreConnection = useCallback( async ({ target }: any) => { if (!skClient) return alert("client is not ready"); @@ -237,20 +254,18 @@ export const WalletPicker = ({ skClient, setWallet, setPhrase }: Props) => { setPhrase(phrases); await skClient.connectKeystore(chains, phrases); - - const walletDataArray = await Promise.all( - chains.map((chain) => skClient.getWalletWithBalance(chain, true)), - ); - + const walletDataArray = chains.map((chain) => skClient.getWallet(chain)); setWallet(walletDataArray.filter(Boolean)); setLoading(false); } catch (e) { console.error(e); alert(e); } + + handleBalanceUpdate(); }, 500); }, - [chains, setWallet, skClient, setPhrase], + [chains, setWallet, skClient, setPhrase, handleBalanceUpdate], ); const handleConnection = useCallback( @@ -258,15 +273,13 @@ export const WalletPicker = ({ skClient, setWallet, setPhrase }: Props) => { if (!skClient) return alert("client is not ready"); setLoading(true); await connectWallet(option, provider); - - const walletDataArray = await Promise.all( - chains.map((chain) => skClient.getWalletWithBalance(chain, true)), - ); - + const walletDataArray = chains.map((chain) => skClient.getWallet(chain)); setWallet(walletDataArray.filter(Boolean)); setLoading(false); + + handleBalanceUpdate(); }, - [chains, connectWallet, setWallet, skClient], + [chains, connectWallet, setWallet, skClient, handleBalanceUpdate], ); const isWalletDisabled = useCallback( @@ -326,6 +339,7 @@ export const WalletPicker = ({ skClient, setWallet, setPhrase }: Props) => { {loading &&
Loading...
} + {balanceLoading &&
Loading balance...
}
diff --git a/playgrounds/vite/src/index.css b/playgrounds/vite/src/index.css index e7d4c19e0..a6330e75b 100644 --- a/playgrounds/vite/src/index.css +++ b/playgrounds/vite/src/index.css @@ -17,3 +17,13 @@ label.label input[type="file"] { .label:valid + span { color: #0f0; } + +html, +body, +input, +button, +select, +textarea { + color: #ccc; + background-color: #000; +}