Skip to content

Commit 59bc5fa

Browse files
committed
fix: code cleanup
1 parent 6a13dc6 commit 59bc5fa

File tree

3 files changed

+77
-12
lines changed

3 files changed

+77
-12
lines changed

src/core/payments/funding.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,10 @@ export function calculateFilecoinPayFundingPlan(options: FilecoinPayFundingPlanO
165165
throw new Error('pricePerTiBPerEpoch is required when pieceSizeBytes is provided')
166166
}
167167

168-
let delta = 0n
168+
let delta: bigint
169169
let projectedDeposit = status.filecoinPayBalance
170170
let projectedRateUsed = status.currentAllowances.rateUsed ?? 0n
171-
let projectedLockupUsed = status.currentAllowances.lockupUsed ?? 0n
171+
let projectedLockupUsed: bigint
172172
let resolvedTargetDeposit: bigint | undefined
173173
let reasonCode: FundingReasonCode = 'none'
174174
const targetType = targetRunwayDays != null ? 'runway-days' : 'deposit'
@@ -275,13 +275,13 @@ export function calculateFilecoinPayFundingPlan(options: FilecoinPayFundingPlanO
275275
*/
276276
export interface PlanFilecoinPayFundingOptions {
277277
synapse: Synapse
278-
targetRunwayDays?: number
279-
targetDeposit?: bigint
280-
pieceSizeBytes?: number
281-
pricePerTiBPerEpoch?: bigint
282-
mode?: FundingMode
283-
allowWithdraw?: boolean
284-
ensureAllowances?: boolean
278+
targetRunwayDays?: number | undefined
279+
targetDeposit?: bigint | undefined
280+
pieceSizeBytes?: number | undefined
281+
pricePerTiBPerEpoch?: bigint | undefined
282+
mode?: FundingMode | undefined
283+
allowWithdraw?: boolean | undefined
284+
ensureAllowances?: boolean | undefined
285285
}
286286

287287
/**
@@ -374,6 +374,17 @@ export async function planFilecoinPayFunding(options: PlanFilecoinPayFundingOpti
374374
}
375375
}
376376

377+
/**
378+
* Execute a Filecoin Pay funding plan by depositing or withdrawing USDFC.
379+
*
380+
* - No-op when `plan.delta` is 0 (returns projected insights unchanged).
381+
* - Deposits when delta > 0, withdraws when delta < 0.
382+
* - Returns updated balances/runway after execution.
383+
*
384+
* @param synapse - Initialized Synapse instance
385+
* @param plan - Funding plan produced by calculate/plan helpers
386+
* @returns Execution result with transaction hash (if any) and updated insights
387+
*/
377388
export async function executeFilecoinPayFunding(
378389
synapse: Synapse,
379390
plan: FilecoinPayFundingPlan

src/payments/fund.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,8 @@ export async function runFund(options: FundOptions): Promise<void> {
231231
spinner.start('Calculating funding plan...')
232232
const planResult = await planFilecoinPayFunding({
233233
synapse,
234-
targetRunwayDays: targetDays,
235-
targetDeposit,
234+
targetRunwayDays: hasDays ? targetDays : undefined,
235+
targetDeposit: hasAmount ? targetDeposit : undefined,
236236
mode: options.mode ?? 'exact',
237237
allowWithdraw: options.mode !== 'minimum',
238238
})
@@ -314,7 +314,7 @@ export async function runFund(options: FundOptions): Promise<void> {
314314
spinner.stop()
315315
console.error(
316316
pc.red(
317-
`✗ Insufficient USDFC in wallet (need ${formatUSDFC(plan.delta)} USDFC, have ${formatUSDFC(plan.delta - plan.walletShortfall)} USDFC)`
317+
`✗ Insufficient USDFC in wallet (need ${formatUSDFC(plan.delta)} USDFC, have ${formatUSDFC(planResult.status.walletUsdfcBalance)} USDFC)`
318318
)
319319
)
320320
cancel('Fund adjustment aborted')

src/test/unit/payments-funding.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,60 @@ describe('planFilecoinPayFunding', () => {
140140
expect(plan.current.runway.state).toBe('no-spend')
141141
expect(plan.projected.runway.state).toBe('no-spend')
142142
})
143+
144+
it('throws when both runway and deposit targets are provided', async () => {
145+
const status = makeStatus({ filecoinPayBalance: 0n, wallet: 1_000n })
146+
vi.spyOn(paymentsIndex, 'getPaymentStatus').mockResolvedValue(status)
147+
vi.spyOn(paymentsIndex, 'checkAndSetAllowances').mockResolvedValue({
148+
updated: false,
149+
currentAllowances: status.currentAllowances,
150+
})
151+
vi.spyOn(paymentsIndex, 'validatePaymentRequirements').mockReturnValue({ isValid: true })
152+
153+
await expect(
154+
planFilecoinPayFunding({
155+
synapse: synapseStub as any,
156+
targetRunwayDays: 10,
157+
targetDeposit: 1_000n,
158+
})
159+
).rejects.toThrow('Specify either targetRunwayDays or targetDeposit, not both')
160+
})
161+
162+
it('throws when no target is provided', async () => {
163+
const status = makeStatus({ filecoinPayBalance: 0n, wallet: 1_000n })
164+
vi.spyOn(paymentsIndex, 'getPaymentStatus').mockResolvedValue(status)
165+
vi.spyOn(paymentsIndex, 'checkAndSetAllowances').mockResolvedValue({
166+
updated: false,
167+
currentAllowances: status.currentAllowances,
168+
})
169+
vi.spyOn(paymentsIndex, 'validatePaymentRequirements').mockReturnValue({ isValid: true })
170+
171+
await expect(
172+
planFilecoinPayFunding({
173+
synapse: synapseStub as any,
174+
})
175+
).rejects.toThrow('A funding target is required')
176+
})
177+
178+
it('fetches pricing when pieceSizeBytes is provided without pricePerTiBPerEpoch', async () => {
179+
const status = makeStatus({ filecoinPayBalance: 0n, wallet: 1_000n })
180+
vi.spyOn(paymentsIndex, 'getPaymentStatus').mockResolvedValue(status)
181+
vi.spyOn(paymentsIndex, 'checkAndSetAllowances').mockResolvedValue({
182+
updated: false,
183+
currentAllowances: status.currentAllowances,
184+
})
185+
vi.spyOn(paymentsIndex, 'validatePaymentRequirements').mockReturnValue({ isValid: true })
186+
187+
const { plan } = await planFilecoinPayFunding({
188+
synapse: synapseStub as any,
189+
targetRunwayDays: 10,
190+
pieceSizeBytes: 1024,
191+
})
192+
193+
expect(plan.pricePerTiBPerEpoch).toBe(1n)
194+
expect(plan.delta).toBeGreaterThan(0n)
195+
expect(plan.reasonCode).toBe('runway-with-piece')
196+
})
143197
})
144198

145199
describe('executeFilecoinPayFunding', () => {

0 commit comments

Comments
 (0)