// npm package
@aztec/aztec-faucet
This application allows someone to obtain a small amount of eth via a http endpoint.
versions
849
maintainers
6
first publish
2025-02-07
publisher
charlielye
tarball
29,896 B
AUTO-PUBLISHED·1 version indexed·latest published 2026-06-04
// exfil path
what is read → where it shipssteals
- ● Seed phrase
sends to
(no destination string extracted — payload may be dynamic / obfuscated)
evidence in excerpt
> const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId); > this.l1Client = createExtendedL1Client(config.l1RpcUrls, this.account, chain.chainInfo); > //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU…
// publisher campaignby charlielye
9 caught packages from this accountThis is not an isolated catch. The same publisher has shipped 8 other packages that our pipeline flagged — the shape of a coordinated campaign, not a one-off. Each link below opens that sibling's analysis.
// offending code· @4.3.1· 3 files flagged
- @4.3.1··AUTO-PUBLISHED·publisher: charlielyeheuristic 64/100static flags 1llm skippednew-publisher:15dmature-packagepublisher-multi-name-burst:11publisher-version-pump:12reads-seed-phrase
// offending code· 3 files flaggedpatterns: 1
--- package/src/config.ts (excerpt) --- import { type L1ReaderConfig, l1ReaderConfigMappings } from '@aztec/ethereum/l1-reader'; import { type ConfigMappingsType, SecretValue, getConfigFromMappings, numberConfigHelper, secretStringConfigHelper, } from '@aztec/foundation/config'; import { EthAddress } from '@aztec/foundation/eth-address'; export type L1AssetConfig = { address: EthAddress; amount: bigint; }; export type FaucetConfig = L1ReaderConfig & { l1Mnemonic?: SecretValue<string>; mnemonicAddressIndex: number; interval: number; ethAmount: string; l1Assets: L1AssetConfig[]; }; export const faucetConfigMapping: ConfigMappingsType<FaucetConfig> = { ...l1ReaderConfigMappings, l1Mnemonic: { env: 'MNEMONIC', description: 'The mnemonic for the faucet account', ...secretStringConfigHelper(), }, mnemonicAddressIndex: { env: 'FAUCET_MNEMONIC_ADDRESS_INDEX', description: 'The address to use', ...numberConfigHelper(0), }, interval: { env: 'FAUCET_INTERVAL_MS', description: 'How often the faucet can be dripped', ...numberConfigHelper(1 * 60 * 60 * 1000), // 1 hour }, ethAmount: { env: 'FAUCET_ETH_AMOUNT', description: 'How much eth the faucet should drip per call', defaultValue: '1.0', }, l1Assets: { env: 'FAUCET_L1_ASSETS', description: 'Which other L1 assets the faucet is able to drip', defaultValue: '', parseEnv(val): L1AssetConfig[] { const assetConfigs = val.split(','); return assetConfigs.flatMap( --- package/src/faucet.ts (excerpt) --- import { createEthereumChain } from '@aztec/ethereum/chain'; import { createExtendedL1Client } from '@aztec/ethereum/client'; import type { ExtendedViemWalletClient } from '@aztec/ethereum/types'; import type { EthAddress } from '@aztec/foundation/eth-address'; import { createLogger } from '@aztec/foundation/log'; import { TestERC20Abi } from '@aztec/l1-artifacts'; import { type Account, type Chain, type GetContractReturnType, type HttpTransport, type LocalAccount, type WalletClient, getContract, parseEther, } from 'viem'; import { mnemonicToAccount } from 'viem/accounts'; import type { FaucetConfig, L1AssetConfig } from './config.js'; type L1Asset = { contract: GetContractReturnType<typeof TestERC20Abi, WalletClient<HttpTransport, Chain, Account>>; amount: bigint; }; export class Faucet { private l1Client: ExtendedViemWalletClient; private dripHistory = new Map<string, Map<string, number>>(); private l1Assets = new Map<string, L1Asset>(); constructor( private config: FaucetConfig, private account: LocalAccount, private timeFn: () => number = Date.now, private log = createLogger('aztec:faucet'), ) { const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId); this.l1Client = createExtendedL1Client(config.l1RpcUrls, this.account, chain.chainInfo); } public static async create(config: FaucetConfig): Promise<Faucet> { if (!config.l1Mnemonic || !config.l1Mnemonic.getValue()) { throw new Error('M --- package/dest/config.d.ts (excerpt) --- import { type L1ReaderConfig } from '@aztec/ethereum/l1-reader'; import { type ConfigMappingsType, SecretValue } from '@aztec/foundation/config'; import { EthAddress } from '@aztec/foundation/eth-address'; export type L1AssetConfig = { address: EthAddress; amount: bigint; }; export type FaucetConfig = L1ReaderConfig & { l1Mnemonic?: SecretValue<string>; mnemonicAddressIndex: number; interval: number; ethAmount: string; l1Assets: L1AssetConfig[]; }; export declare const faucetConfigMapping: ConfigMappingsType<FaucetConfig>; export declare function getFaucetConfigFromEnv(): FaucetConfig; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLGNBQWMsRUFBMEIsTUFBTSwyQkFBMkIsQ0FBQztBQUN4RixPQUFPLEVBQ0wsS0FBSyxrQkFBa0IsRUFDdkIsV0FBVyxFQUlaLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE1BQU0sTUFBTSxhQUFhLEdBQUc7SUFDMUIsT0FBTyxFQUFFLFVBQVUsQ0FBQztJQUNwQixNQUFNLEVBQUUsTUFBTSxDQUFDO0NBQ2hCLENBQUM7QUFFRixNQUFNLE1BQU0sWUFBWSxHQUFHLGNBQWMsR0FBRztJQUMxQyxVQUFVLENBQUMsRUFBRSxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakMsb0JBQW9CLEVBQUUsTUFBTSxDQUFDO0lBQzdCLFFBQVEsRUFBRSxNQUFNLENBQUM7SUFDakIsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQixRQUFRLEVBQUUsYUFBYSxFQUFFLENBQUM7Q0FDM0IsQ0FBQztBQUVGLGVBQU8sTUFBTSxtQkFBbUIsRUFBRSxrQkFBa0IsQ0FBQyxZQUFZLENBcUNoRSxDQUFDO0FBRUYsd0JBQWdCLHNCQUFzQ
