Skip to content

Commit e44bcf8

Browse files
feat: sync CLI with API changes
1 parent 5b17b4f commit e44bcf8

4 files changed

Lines changed: 107 additions & 3 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@blindpay/cli",
33
"type": "module",
4-
"version": "0.1.1",
4+
"version": "0.1.2",
55
"description": "Blindpay CLI - manage receivers, bank accounts, payouts, payins, and more from the terminal",
66
"license": "MIT",
77
"author": "Blindpay <gabriel@blindpay.com> (https://blindpay.com/)",

src/__tests__/resources.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,30 @@ describe('Receivers', () => {
195195
supporting_document_file: 'https://example.com/doc.pdf',
196196
})
197197
})
198+
199+
test('fetches the open RFI for a receiver', async () => {
200+
mockResponse.body = { id: 'rfi_1', status: 'pending', receiver_id: 're_xyz' }
201+
await resources.getReceiverRfi('re_xyz', { json: true })
202+
expect(lastCall().method).toBe('GET')
203+
expect(lastCall().url).toBe(`${BASE}/receivers/re_xyz/rfi`)
204+
})
205+
206+
test('submits an RFI response with a parsed --body JSON string', async () => {
207+
mockResponse.body = { success: true }
208+
await resources.submitReceiverRfi('re_xyz', {
209+
body: '{"address":"123 Main St","city":"Austin"}',
210+
json: true,
211+
})
212+
expect(lastCall().method).toBe('POST')
213+
expect(lastCall().url).toBe(`${BASE}/receivers/re_xyz/rfi`)
214+
expect(lastCall().body).toEqual({ address: '123 Main St', city: 'Austin' })
215+
})
216+
217+
test('exits with code 1 when --body is not valid JSON', async () => {
218+
await expect(
219+
resources.submitReceiverRfi('re_xyz', { body: 'not-json', json: true }),
220+
).rejects.toThrow('__test_exit__1')
221+
})
198222
})
199223

200224
describe('Bank Accounts', () => {
@@ -237,6 +261,14 @@ describe('Bank Accounts', () => {
237261
account_class: null,
238262
country: null,
239263
swift_ifsc_branch_code: null,
264+
sepa_iban: null,
265+
sepa_beneficiary_address_line_1: null,
266+
sepa_beneficiary_address_line_2: null,
267+
sepa_beneficiary_city: null,
268+
sepa_beneficiary_country: null,
269+
sepa_beneficiary_legal_name: null,
270+
sepa_beneficiary_postal_code: null,
271+
sepa_beneficiary_state_province_region: null,
240272
})
241273
})
242274

src/commands/resources.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,36 @@ export async function deleteReceiver(id: string, options: { json?: boolean } = {
216216
}
217217
}
218218

219+
export async function getReceiverRfi(receiverId: string, options: { json: boolean }) {
220+
try {
221+
const ctx = resolveContext()
222+
const rfi = await apiGet(ctx, `${instancePath(ctx)}/receivers/${receiverId}/rfi`)
223+
printResult(rfi, options.json, ['id', 'status', 'receiver_id', 'expires_at', 'created_at'])
224+
}
225+
catch (e) {
226+
handleApiError(e, options.json)
227+
}
228+
}
229+
230+
export async function submitReceiverRfi(receiverId: string, options: { body: string, json: boolean }) {
231+
let parsedBody: Record<string, unknown>
232+
try {
233+
parsedBody = JSON.parse(options.body) as Record<string, unknown>
234+
}
235+
catch (e) {
236+
exitWithError(`Invalid --body JSON: ${(e as Error).message}`, 1, options.json)
237+
}
238+
try {
239+
const ctx = resolveContext()
240+
const res = await apiPost<{ success: boolean }>(ctx, `${instancePath(ctx)}/receivers/${receiverId}/rfi`, parsedBody)
241+
clack.log.success('RFI response submitted')
242+
if (options.json) console.log(formatOutput(res, true))
243+
}
244+
catch (e) {
245+
handleApiError(e, options.json)
246+
}
247+
}
248+
219249
// Bank Accounts
220250
export async function listBankAccounts(options: { receiverId: string, json: boolean }) {
221251
try {
@@ -254,6 +284,14 @@ export async function createBankAccount(options: {
254284
accountClass?: string
255285
country?: string
256286
swiftIfscBranchCode?: string
287+
sepaIban?: string
288+
sepaBeneficiaryAddressLine1?: string
289+
sepaBeneficiaryAddressLine2?: string
290+
sepaBeneficiaryCity?: string
291+
sepaBeneficiaryCountry?: string
292+
sepaBeneficiaryLegalName?: string
293+
sepaBeneficiaryPostalCode?: string
294+
sepaBeneficiaryStateProvinceRegion?: string
257295
json: boolean
258296
}) {
259297
try {
@@ -270,6 +308,14 @@ export async function createBankAccount(options: {
270308
account_class: options.accountClass ?? null,
271309
country: options.country ?? null,
272310
swift_ifsc_branch_code: options.swiftIfscBranchCode ?? null,
311+
sepa_iban: options.sepaIban ?? null,
312+
sepa_beneficiary_address_line_1: options.sepaBeneficiaryAddressLine1 ?? null,
313+
sepa_beneficiary_address_line_2: options.sepaBeneficiaryAddressLine2 ?? null,
314+
sepa_beneficiary_city: options.sepaBeneficiaryCity ?? null,
315+
sepa_beneficiary_country: options.sepaBeneficiaryCountry ?? null,
316+
sepa_beneficiary_legal_name: options.sepaBeneficiaryLegalName ?? null,
317+
sepa_beneficiary_postal_code: options.sepaBeneficiaryPostalCode ?? null,
318+
sepa_beneficiary_state_province_region: options.sepaBeneficiaryStateProvinceRegion ?? null,
273319
}
274320
const ba = await apiPost<{ id: string, type: string }>(ctx, `${instancePath(ctx)}/receivers/${options.receiverId}/bank-accounts`, body)
275321
clack.log.success(`Created bank account ${ba.id} (${ba.type})`)

src/index.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ import {
4545
listAvailableRails,
4646
getAvailableBankDetails,
4747
createReceiverLimitIncrease,
48+
getReceiverRfi,
49+
submitReceiverRfi,
4850
listWallets,
4951
getWallet,
5052
getWalletBalance,
@@ -145,7 +147,9 @@ Examples:
145147
$ blindpay receivers create --email user@example.com --name "John Doe" --country US
146148
$ blindpay receivers create --type business --email biz@co.com --legal-name "Acme Inc"
147149
$ blindpay receivers update <id> --kyc-status approved
148-
$ blindpay receivers delete <id>`)
150+
$ blindpay receivers delete <id>
151+
$ blindpay receivers get_rfi <receiver-id>
152+
$ blindpay receivers submit_rfi <receiver-id> --body '{"address":"..."}'`)
149153

150154
receivers
151155
.command('list')
@@ -217,6 +221,19 @@ receivers
217221
.option('--json', 'Output as JSON', false)
218222
.action((id, opts) => createReceiverLimitIncrease(id, opts))
219223

224+
receivers
225+
.command('get_rfi <receiver-id>')
226+
.description('Get the open RFI for a receiver')
227+
.option('--json', 'Output as JSON', false)
228+
.action((receiverId, opts) => getReceiverRfi(receiverId, opts))
229+
230+
receivers
231+
.command('submit_rfi <receiver-id>')
232+
.description('Submit an RFI response for a receiver')
233+
.requiredOption('--body <json>', 'RFI response as a JSON string')
234+
.option('--json', 'Output as JSON', false)
235+
.action((receiverId, opts) => submitReceiverRfi(receiverId, opts))
236+
220237
// ── Bank Accounts ───────────────────────────────────────────────────────
221238
const bankAccounts = program.command('bank_accounts').description('Manage bank accounts')
222239
.addHelpText('after', `
@@ -225,6 +242,7 @@ Examples:
225242
$ blindpay bank_accounts get <id> --receiver-id <receiver-id>
226243
$ blindpay bank_accounts create --receiver-id <id> --type ach --routing-number 021000021 --account-number 123456789
227244
$ blindpay bank_accounts create --receiver-id <id> --type pix --pix-key user@email.com
245+
$ blindpay bank_accounts create --receiver-id <id> --type sepa --sepa-iban DE89370400440532013000
228246
$ blindpay bank_accounts delete <id> --receiver-id <receiver-id>`)
229247

230248
bankAccounts
@@ -245,7 +263,7 @@ bankAccounts
245263
.command('create')
246264
.description('Create a new bank account')
247265
.requiredOption('--receiver-id <id>', 'Receiver ID')
248-
.option('--type <type>', 'Bank account type (ach, wire, pix, etc.)', 'ach')
266+
.option('--type <type>', 'Bank account type (ach, wire, pix, sepa, etc.)', 'ach')
249267
.option('--name <name>', 'Account name')
250268
.option('--beneficiary-name <name>', 'Beneficiary name')
251269
.option('--routing-number <number>', 'Routing number')
@@ -256,6 +274,14 @@ bankAccounts
256274
.option('--recipient-relationship <rel>', 'Recipient relationship')
257275
.option('--country <country>', 'Country code')
258276
.option('--swift-ifsc-branch-code <code>', 'SWIFT/IFSC branch code (international_swift accounts)')
277+
.option('--sepa-iban <iban>', 'SEPA IBAN')
278+
.option('--sepa-beneficiary-address-line-1 <address>', 'SEPA beneficiary address line 1')
279+
.option('--sepa-beneficiary-address-line-2 <address>', 'SEPA beneficiary address line 2')
280+
.option('--sepa-beneficiary-city <city>', 'SEPA beneficiary city')
281+
.option('--sepa-beneficiary-country <country>', 'SEPA beneficiary country code')
282+
.option('--sepa-beneficiary-legal-name <name>', 'SEPA beneficiary legal name')
283+
.option('--sepa-beneficiary-postal-code <code>', 'SEPA beneficiary postal code')
284+
.option('--sepa-beneficiary-state-province-region <region>', 'SEPA beneficiary state/province/region')
259285
.option('--json', 'Output as JSON', false)
260286
.action(opts => createBankAccount(opts))
261287

0 commit comments

Comments
 (0)