Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .yarnrc.yml
Comment thread
gomesalexandre marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ nodeLinker: node-modules

npmAuthToken: "${NPM_AUTH-fallback}"

npmRegistryServer: "https://registry.npmjs.org"
npmRegistryServer: "http://127.0.0.1:4873"

plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
Expand Down
6 changes: 5 additions & 1 deletion headers/csps/chains/zcash.ts
Comment thread
gomesalexandre marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@ const mode = process.env.MODE ?? process.env.NODE_ENV ?? 'development'
const env = loadEnv(mode, process.cwd(), '')

export const csp: Csp = {
'connect-src': [env.VITE_UNCHAINED_ZCASH_HTTP_URL, env.VITE_UNCHAINED_ZCASH_WS_URL],
'connect-src': [
env.VITE_UNCHAINED_ZCASH_HTTP_URL,
env.VITE_UNCHAINED_ZCASH_WS_URL,
'https://api.blockchair.com',
],
}
38 changes: 20 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,24 @@
"@shapeshiftoss/chain-adapters": "workspace:^",
"@shapeshiftoss/contracts": "workspace:^",
"@shapeshiftoss/errors": "workspace:^",
"@shapeshiftoss/hdwallet-coinbase": "1.62.23",
"@shapeshiftoss/hdwallet-core": "1.62.23",
"@shapeshiftoss/hdwallet-gridplus": "1.62.23",
"@shapeshiftoss/hdwallet-keepkey": "1.62.23",
"@shapeshiftoss/hdwallet-keepkey-webusb": "1.62.23",
"@shapeshiftoss/hdwallet-keplr": "1.62.23",
"@shapeshiftoss/hdwallet-ledger": "1.62.23",
"@shapeshiftoss/hdwallet-ledger-webhid": "1.62.23",
"@shapeshiftoss/hdwallet-ledger-webusb": "1.62.23",
"@shapeshiftoss/hdwallet-metamask-multichain": "1.62.23",
"@shapeshiftoss/hdwallet-native": "1.62.23",
"@shapeshiftoss/hdwallet-native-vault": "1.62.23",
"@shapeshiftoss/hdwallet-phantom": "1.62.23",
"@shapeshiftoss/hdwallet-trezor": "1.62.23",
"@shapeshiftoss/hdwallet-trezor-connect": "1.62.23",
"@shapeshiftoss/hdwallet-vultisig": "1.62.23",
"@shapeshiftoss/hdwallet-walletconnect": "1.62.23",
"@shapeshiftoss/hdwallet-walletconnectv2": "1.62.23",
"@shapeshiftoss/hdwallet-coinbase": "1.62.25",
"@shapeshiftoss/hdwallet-core": "1.62.25",
"@shapeshiftoss/hdwallet-gridplus": "1.62.25",
"@shapeshiftoss/hdwallet-keepkey": "1.62.25",
"@shapeshiftoss/hdwallet-keepkey-webusb": "1.62.25",
"@shapeshiftoss/hdwallet-keplr": "1.62.25",
"@shapeshiftoss/hdwallet-ledger": "1.62.26-ledger-zcash.17",
"@shapeshiftoss/hdwallet-ledger-webhid": "1.62.26-ledger-zcash.17",
"@shapeshiftoss/hdwallet-ledger-webusb": "1.62.26-ledger-zcash.17",
"@shapeshiftoss/hdwallet-metamask-multichain": "1.62.25",
"@shapeshiftoss/hdwallet-native": "1.62.25",
"@shapeshiftoss/hdwallet-native-vault": "1.62.25",
"@shapeshiftoss/hdwallet-phantom": "1.62.25",
"@shapeshiftoss/hdwallet-trezor": "1.62.25",
"@shapeshiftoss/hdwallet-trezor-connect": "1.62.25",
"@shapeshiftoss/hdwallet-vultisig": "1.62.25",
"@shapeshiftoss/hdwallet-walletconnect": "1.62.25",
"@shapeshiftoss/hdwallet-walletconnectv2": "1.62.25",
"@shapeshiftoss/swapper": "workspace:^",
"@shapeshiftoss/types": "workspace:^",
"@shapeshiftoss/unchained-client": "workspace:^",
Expand Down Expand Up @@ -311,6 +311,8 @@
"@typescript-eslint/eslint-plugin": "^8.16.0",
"eslint-plugin-import": "^2.31.0",
"react-router@^6.30.0": "patch:react-router@npm%3A6.30.0#./.yarn/patches/react-router-npm-6.30.0-cd12804d8c.patch",
"@ledgerhq/hw-app-btc": "10.12.0",
"@shapeshiftoss/hdwallet-ledger": "1.62.26-ledger-zcash.17",
Comment thread
gomesalexandre marked this conversation as resolved.
Outdated
"react-router@6.30.0": "patch:react-router@npm%3A6.30.0#./.yarn/patches/react-router-npm-6.30.0-cd12804d8c.patch",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/chain-adapters/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
"dependencies": {
"@mysten/sui": "1.45.0",
"@shapeshiftoss/caip": "workspace:^",
"@shapeshiftoss/hdwallet-core": "1.62.23",
"@shapeshiftoss/hdwallet-ledger": "1.62.23",
"@shapeshiftoss/hdwallet-core": "1.62.26-ledger-zcash.17",
"@shapeshiftoss/hdwallet-ledger": "1.62.26-ledger-zcash.17",
"@shapeshiftoss/types": "workspace:^",
"@shapeshiftoss/unchained-client": "workspace:^",
"@shapeshiftoss/utils": "workspace:^",
Expand Down
1 change: 1 addition & 0 deletions packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { AssetId } from '@shapeshiftoss/caip'
import { ASSET_REFERENCE, monadAssetId } from '@shapeshiftoss/caip'
import type { RootBip44Params } from '@shapeshiftoss/types'
import { KnownChainIds } from '@shapeshiftoss/types'
// @ts-ignore fml that'll do for now
Comment thread
gomesalexandre marked this conversation as resolved.
Outdated
import { Contract, Interface, JsonRpcProvider } from 'ethers'

import { ErrorHandler } from '../../error/ErrorHandler'
Expand Down
14 changes: 10 additions & 4 deletions packages/chain-adapters/src/utils/ledgerAppGate.ts
Comment thread
gomesalexandre marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,16 @@ export const verifyLedgerAppOpen = async (chainId: ChainId | KnownChainIds, wall
try {
await wallet.validateCurrentApp(coin)
return true
} catch {
} catch (err) {
return false
}
}

if (await isAppOpen()) return
const appAlreadyOpen = await isAppOpen()
if (appAlreadyOpen) return

let intervalId: NodeJS.Timeout | undefined
let attempts = 0

try {
await new Promise<void>((resolve, reject) => {
Expand All @@ -122,15 +124,19 @@ export const verifyLedgerAppOpen = async (chainId: ChainId | KnownChainIds, wall
wallet.openApp(appName)

intervalId = setInterval(async () => {
if (!(await isAppOpen())) return
attempts++

if (!(await isAppOpen())) {
return
}

// emit event to trigger modal close
emitter.emit('LedgerAppOpened')
clearInterval(intervalId)
resolve()
}, 1000)
})
} catch {
} catch (err) {
clearInterval(intervalId)
throw new ChainAdapterError('Ledger app open cancelled', {
translation: 'chainAdapters.errors.ledgerAppOpenCancelled',
Expand Down
31 changes: 31 additions & 0 deletions packages/chain-adapters/src/utxo/UtxoBaseAdapter.ts
Comment thread
gomesalexandre marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,13 @@ export abstract class UtxoBaseAdapter<T extends UtxoChainId> implements IChainAd

this.assertIsAccountTypeSupported(accountType)

console.log(`[${this.coinName} Adapter] buildSendApiTransaction - fetching UTXOs for xpub:`, xpub)
console.log(`[${this.coinName} Adapter] chainSpecific.from (UTXO filter):`, from)

const utxos = await this.providers.http.getUtxos({ pubkey: xpub })

console.log(`[${this.coinName} Adapter] Fetched ${utxos.length} UTXOs:`, JSON.stringify(utxos, null, 2))

const coinSelectResult = utxoSelect({
utxos,
from,
Expand All @@ -305,6 +310,13 @@ export abstract class UtxoBaseAdapter<T extends UtxoChainId> implements IChainAd
assetId: this.assetId,
})

console.log(`[${this.coinName} Adapter] coinSelect result:`, JSON.stringify({
inputsCount: coinSelectResult?.inputs?.length,
inputs: coinSelectResult?.inputs,
outputsCount: coinSelectResult?.outputs?.length,
fee: coinSelectResult?.fee,
}, null, 2))

if (!coinSelectResult?.inputs || !coinSelectResult?.outputs) {
throw new Error('error selecting utxos')
}
Expand Down Expand Up @@ -340,8 +352,17 @@ export abstract class UtxoBaseAdapter<T extends UtxoChainId> implements IChainAd

const signTxInputs: BTCSignTxInput[] = []
for (const input of inputs) {
console.log(`[${this.coinName} Adapter] Fetching transaction hex for input:`, {
txid: input.txid,
vout: input.vout,
value: input.value,
})

const data = await this.providers.http.getTransaction({ txid: input.txid })

console.log(`[${this.coinName} Adapter] Got transaction hex, length:`, data.hex?.length || 0)
console.log(`[${this.coinName} Adapter] Transaction blockHeight:`, data.blockHeight)

signTxInputs.push({
// UTXO inputs are not guaranteed to have paths.
// They will in the case of an /api/v1/account/<xpub>/utxos account
Expand All @@ -355,6 +376,9 @@ export abstract class UtxoBaseAdapter<T extends UtxoChainId> implements IChainAd
vout: input.vout,
txid: input.txid,
hex: data.hex,
// For Zcash, we need to pass the blockHeight and txid of each input transaction
// so Ledger can add them to the PSBT and determine the correct consensus branch ID
...(this.coinName === 'Zcash' && data.blockHeight && { blockHeight: data.blockHeight }),
Comment thread
gomesalexandre marked this conversation as resolved.
Outdated
})
}

Expand Down Expand Up @@ -385,6 +409,13 @@ export abstract class UtxoBaseAdapter<T extends UtxoChainId> implements IChainAd
opReturnData,
} as SignTx<T>

console.log(`[${this.coinName} Adapter] buildSendApiTransaction result:`, JSON.stringify({
coin: this.coinName,
inputsCount: signTxInputs.length,
outputsCount: signTxOutputs.length,
opReturnData,
}, null, 2))

return txToSign
} catch (err) {
return ErrorHandler(err, {
Expand Down
32 changes: 32 additions & 0 deletions packages/chain-adapters/src/utxo/zcash/ZcashChainAdapter.ts
Comment thread
gomesalexandre marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { KnownChainIds, UtxoAccountType } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'

import { ChainAdapterDisplayName } from '../../types'
import type { BroadcastTransactionInput } from '../../types'
import type { ChainAdapterArgs as BaseChainAdapterArgs } from '../UtxoBaseAdapter'
import { UtxoBaseAdapter } from '../UtxoBaseAdapter'

Expand Down Expand Up @@ -57,4 +58,35 @@ export class ChainAdapter extends UtxoBaseAdapter<KnownChainIds.ZcashMainnet> {
getFeeAssetId(): AssetId {
return this.assetId
}

async broadcastTransaction({ hex }: Pick<BroadcastTransactionInput, 'hex'>): Promise<string> {
console.log('[Zcash Adapter] Broadcasting via Blockchair monkey-patch:', {
hexLength: hex.length,
hexSample: hex.substring(0, 64),
})

try {
const response = await fetch('https://api.blockchair.com/zcash/push/transaction', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ data: hex }),
})

const result = await response.json()
console.log('[Zcash Adapter] Blockchair response:', result)

if (result.context.code !== 200) {
const errorMsg = result.context.error || 'Transaction broadcast failed'
console.error('[Zcash Adapter] Blockchair error:', errorMsg)
throw new Error(errorMsg)
}

const txHash = result.data?.transaction_hash
console.log('[Zcash Adapter] Broadcast successful, txHash:', txHash)
return txHash || ''
} catch (err) {
console.error('[Zcash Adapter] Blockchair broadcast failed:', err)
throw err
}
}
}
4 changes: 2 additions & 2 deletions packages/swapper/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
"@jup-ag/api": "^6.0.30",
"@shapeshiftoss/bitcoinjs-lib": "7.0.0-shapeshift.0",
"@shapeshiftoss/caip": "workspace:^",
"@shapeshiftoss/chain-adapters": "workspace:^",
"@shapeshiftoss/chain-adapters": "*",
Comment thread
gomesalexandre marked this conversation as resolved.
Outdated
"@shapeshiftoss/contracts": "workspace:^",
"@shapeshiftoss/hdwallet-core": "1.62.23",
"@shapeshiftoss/hdwallet-core": "1.62.26-ledger-zcash.17",
"@shapeshiftoss/types": "workspace:^",
"@shapeshiftoss/unchained-client": "workspace:^",
"@shapeshiftoss/utils": "workspace:^",
Expand Down
2 changes: 2 additions & 0 deletions src/context/WalletProvider/Ledger/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
suiAssetId,
thorchainAssetId,
tronAssetId,
zecAssetId,
} from '@shapeshiftoss/caip'
import { uniq } from 'lodash'

Expand All @@ -30,6 +31,7 @@ export const availableLedgerAppAssetIds = [
dogeAssetId,
bchAssetId,
ltcAssetId,
...(getConfig().VITE_FEATURE_ZCASH ? [zecAssetId] : []),
ethAssetId,
thorchainAssetId,
cosmosAssetId,
Expand Down
6 changes: 2 additions & 4 deletions src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import { KeyManager } from '@/context/WalletProvider/KeyManager'
import { useIsSnapInstalled } from '@/hooks/useIsSnapInstalled/useIsSnapInstalled'
import { useWallet } from '@/hooks/useWallet/useWallet'
import { METAMASK_RDNS } from '@/lib/mipd'
import { isNativeHDWallet } from '@/lib/utils'
import { isLedgerHDWallet, isNativeHDWallet } from '@/lib/utils'
import { selectAccountIdsByChainIdFilter } from '@/state/slices/portfolioSlice/selectors'
import { selectFeatureFlag } from '@/state/slices/selectors'
import { store, useAppSelector } from '@/state/store'
Expand Down Expand Up @@ -159,9 +159,7 @@ export const walletSupportsChain = ({
!(wallet instanceof GridPlusHDWallet)
)
case zecChainId:
// Only native wallet supports ZCash for now
// TODO(gomes): include more as more wallets supported for ZCash
return supportsBTC(wallet) && isNativeHDWallet(wallet)
return supportsBTC(wallet) && (isNativeHDWallet(wallet) || isLedgerHDWallet(wallet))
case ethChainId:
return supportsETH(wallet)
case avalancheChainId:
Expand Down
Loading