import {
asStringArray,
DEFAULT_PRODUCTS,
SANDBOX_INSTITUTION_ID,
mutationPreview,
plaidRequest,
requireString,
type MutationGuardInput,
} from './plaid-core.ts'
export type CreateSandboxPublicTokenInput = MutationGuardInput & {
institutionId?: string
products?: string[]
}
/**
* Create a Sandbox public_token without Plaid Link
* (`/sandbox/public_token/create`). Defaults to dry-run; live create needs
* `confirm: true`.
*
* Uses Plaid's published Sandbox institution defaults. This helper never
* accepts a bank username or password — do not collect those in chat.
*/
export async function createSandboxPublicToken(input: CreateSandboxPublicTokenInput = {}) {
if (input.environment === 'production') {
throw new Error('createSandboxPublicToken is Sandbox-only. Omit environment or pass environment: "sandbox".')
}
const institutionId = input.institutionId ?? SANDBOX_INSTITUTION_ID
const products = asStringArray(input.products, DEFAULT_PRODUCTS)
const preview = mutationPreview(input, {
action: 'create sandbox public token',
method: 'POST',
path: '/sandbox/public_token/create',
body: {
institution_id: institutionId,
initial_products: products,
},
})
if (preview) return preview
const data = await plaidRequest({
...input,
environment: 'sandbox',
path: '/sandbox/public_token/create',
body: {
institution_id: requireString(institutionId, 'institutionId'),
initial_products: products,
},
})
return {
public_token: data?.public_token ?? null,
request_id: data?.request_id ?? null,
note: 'Exchange this public_token with confirm: true, then save the access_token as plaidAccessToken. Never store a bank password.',
}
}
export default createSandboxPublicToken