Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions .changeset/fund-command-testnet-default.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'mppx': patch
---

Defaulted account faucet funding to testnet unless a network or RPC URL was specified.
26 changes: 19 additions & 7 deletions src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
printResponseHeaders,
prompt,
resolveChain,
resolveFundingNetwork,
resolveRpcUrl,
} from './utils.js'

Expand Down Expand Up @@ -704,8 +705,9 @@ const account = Cli.create('account', {
const addrDisplay = explorerUrl
? link(`${explorerUrl}/address/${acct.address}`, acct.address)
: acct.address
const rpcUrl = resolveRpcUrl(c.options.rpcUrl, { network: c.options.network })
resolveChain({ network: c.options.network, rpcUrl })
const fundingNetwork = resolveFundingNetwork(c.options)
const rpcUrl = resolveRpcUrl(c.options.rpcUrl, { network: fundingNetwork })
resolveChain({ network: fundingNetwork, rpcUrl })
.then((chain) => createClient({ chain, transport: http(rpcUrl) }))
.then((client) =>
import('viem/tempo').then(({ Actions }) =>
Expand All @@ -715,6 +717,11 @@ const account = Cli.create('account', {
return outputResult(c, { address: acct.address, name: resolvedName }, () => {
console.log(`Account "${resolvedName}" saved to keychain.`)
console.log(pc.dim(`Address ${addrDisplay}`))
console.log(
pc.dim(
`Fund testnet tokens: mppx account fund --account ${resolvedName} --network testnet`,
),
)
})
},
})
Expand Down Expand Up @@ -840,8 +847,9 @@ const account = Cli.create('account', {
return c.error({ code: 'ACCOUNT_NOT_FOUND', message: 'No account found.', exitCode: 69 })
}
const acct = privateKeyToAccount(key as `0x${string}`)
const rpcUrl = resolveRpcUrl(c.options.rpcUrl, { network: c.options.network })
const chain = await resolveChain({ network: c.options.network, rpcUrl })
const fundingNetwork = resolveFundingNetwork(c.options)
const rpcUrl = resolveRpcUrl(c.options.rpcUrl, { network: fundingNetwork })
const chain = await resolveChain({ network: fundingNetwork, rpcUrl })
const client = createClient({ chain, transport: http(rpcUrl) })
if (!structured) console.log(`Funding "${accountName}" on ${chainName(chain)}`)
try {
Expand All @@ -864,14 +872,18 @@ const account = Cli.create('account', {
},
)
} catch (err) {
const message = err instanceof Error ? err.message : String(err)
if (structured)
return c.error({
code: 'FUNDING_FAILED',
message: err instanceof Error ? err.message : String(err),
message,
exitCode: 1,
})
console.error('Funding failed:', err instanceof Error ? err.message : err)
return undefined as never
return c.error({
code: 'FUNDING_FAILED',
message: `Funding failed: ${message}`,
exitCode: 1,
})
}
},
})
Expand Down
26 changes: 25 additions & 1 deletion src/cli/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { tempo as tempoMainnet, tempoModerato } from 'viem/tempo/chains'
import { afterEach, describe, expect, test } from 'vp/test'

import { networkRpcUrls, resolveChain, resolveRpcUrl } from './utils.js'
import { networkRpcUrls, resolveChain, resolveFundingNetwork, resolveRpcUrl } from './utils.js'

describe('resolveRpcUrl', () => {
afterEach(() => {
Expand Down Expand Up @@ -52,6 +52,30 @@ describe('resolveRpcUrl', () => {
})
})

describe('resolveFundingNetwork', () => {
afterEach(() => {
delete process.env.MPPX_RPC_URL
delete process.env.RPC_URL
})

test('defaults faucet funding to testnet', () => {
expect(resolveFundingNetwork()).toBe('testnet')
})

test('keeps explicit network selection', () => {
expect(resolveFundingNetwork({ network: 'mainnet' })).toBe('mainnet')
})

test('does not override explicit rpc url', () => {
expect(resolveFundingNetwork({ rpcUrl: 'https://explicit.example.com' })).toBeUndefined()
})

test('does not override env rpc urls', () => {
process.env.MPPX_RPC_URL = 'https://env.example.com'
expect(resolveFundingNetwork()).toBeUndefined()
})
})

describe('resolveChain', () => {
afterEach(() => {
delete process.env.MPPX_RPC_URL
Expand Down
10 changes: 10 additions & 0 deletions src/cli/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,16 @@ export function resolveRpcUrl(
)
}

/** Select the default network for faucet funding without overriding explicit RPC configuration. */
export function resolveFundingNetwork(
options: { network?: Network | undefined; rpcUrl?: string | undefined } = {},
): Network | undefined {
if (options.network) return options.network
if (options.rpcUrl) return undefined
if (process.env.MPPX_RPC_URL?.trim() || process.env.RPC_URL?.trim()) return undefined
return 'testnet'
}

export async function resolveChain(
opts: { network?: Network | undefined; rpcUrl?: string | undefined } = {},
): Promise<Chain> {
Expand Down