@t-0/provider-starter-ts
v1.1.42
Published
CLI tool to scaffold a Node.js t-0 Network integration service
Readme
T-0 Provider Starter -- TypeScript
CLI tool to scaffold a Node.js TypeScript provider project for the T-0 Network.
Quick Start
npx @t-0/provider-starter-tsThe CLI will prompt for a project name, then create a ready-to-run project with a secp256k1 keypair (via OpenSSL), environment config, provider service stubs, and a Dockerfile.
t0-init init --lang=node my-provider scaffolds the same template with the unified CLI; run npm install && npm run dev in the new project (the CLI prints this as its final step). Installation and options are in cli/README.md.
Generated Project Structure
your-project-name/
├── src/
│ ├── index.ts # Entry point
│ ├── service.ts # Phase 2: ProviderService handlers
│ ├── payment_intent_pay_in_service.ts # Phase 3A: PayInProviderService handler
│ ├── payment_intent_beneficiary_service.ts # Phase 3B: BeneficiaryService handler
│ ├── publish_quotes.ts # Phase 1: payout quote publishing
│ ├── get_quote.ts # Phase 1: quote retrieval
│ ├── publish_payment_intent_quotes.ts # Phase 3A: pay-in quote publishing
│ ├── get_payment_intent_quote.ts # Phase 3B: indicative quote retrieval
│ ├── create_payment_intent.ts # Phase 3B: create a payment intent
│ ├── confirm_funds_received.ts # Phase 3A: confirm funds received
│ ├── submit_payment.ts # Phase 2: payment submission
│ ├── complete_manual_aml_check.ts # Phase 2: manual AML check completion
│ └── lib.ts # Utility functions
├── Dockerfile # Docker configuration
├── .env # Environment variables (with generated keys)
├── .env.example # Example environment file
├── .gitignore # Git ignore rules
├── package.json # Project dependencies
└── tsconfig.json # TypeScript configurationKey Files to Modify
| File | Purpose |
|------|---------|
| src/service.ts | Implement your payment processing logic. Look for TODO comments. |
| src/publish_quotes.ts | Replace sample quotes with your FX rate source. |
Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| PROVIDER_PRIVATE_KEY | Yes | Auto-generated | Your secp256k1 private key (hex) |
| NETWORK_PUBLIC_KEY | Yes | Sandbox key | T-0 Network public key for signature verification |
| TZERO_ENDPOINT | No | https://api-sandbox.t-0.network | T-0 Network API endpoint |
| PORT | No | 3000 | Server port |
| QUOTE_PUBLISHING_INTERVAL | No | 5000 | Quote publishing frequency in milliseconds |
Getting Started
Phase 1: Quoting
- Copy the generated public key from the comment in
.envand share it with the T-0 team to register your provider. - Implement your quote publishing logic in
src/publish_quotes.ts. - Start the dev server (
npm run dev) and verify quotes are published. - Confirm quote retrieval works by checking the output of
getQuoteinsrc/index.ts.
Phase 2: Payments
- Implement
updatePaymenthandler insrc/service.ts. - Deploy your service and share the base URL with the T-0 team.
- Implement
payOuthandler insrc/service.ts. - Test payment submission by uncommenting the
submitPaymentcall insrc/index.ts. - Coordinate with the T-0 team to test end-to-end payment flows.
- (Optional) If your
payOuthandler responds withmanualAmlCheck, report the check outcome viasrc/complete_manual_aml_check.ts.
Phase 3: Payment Intent Flow
The payment intent flow is independent of Phase 2. It is an asynchronous pay-in flow where an end-user pays a pay-in provider in fiat (bank transfer, mobile money, etc.) and a beneficiary provider receives settlement on the crypto side. Quotes are indicative until funds are received, settlement happens periodically, and a confirmation code links the end-user's payment back to a specific payment intent.
Implement one of the two sub-phases below depending on your role. If you participate on both sides, implement both.
Phase 3A -- Pay-In Provider role (skip if you're a beneficiary):
- Step 3A.1 Replace the sample pay-in quote publishing in
src/publish_payment_intent_quotes.tswith your own. - Step 3A.2 Implement
getPaymentDetailsinsrc/payment_intent_pay_in_service.ts-- return bank account / mobile money details plus a payment reference the end-user will include in their transfer. - Step 3A.3 When you detect the end-user's fiat payment, call
confirmFundsReceived(seesrc/confirm_funds_received.ts).
Phase 3B -- Beneficiary Provider role (skip if you're pay-in):
- Step 3B.1 Verify indicative quotes are returned (
src/get_payment_intent_quote.ts). - Step 3B.2 Create payment intents for your end-users via
createPaymentIntent(seesrc/create_payment_intent.ts). - Step 3B.3 Implement
paymentIntentUpdateinsrc/payment_intent_beneficiary_service.tsto receive notifications when funds are received.
If you only play one role, delete the files for the other role and remove the corresponding r.service(...) registration in src/index.ts.
Available Commands
npm run dev # Run in development mode with ts-node
npm run build # Compile TypeScript to dist/
npm start # Run compiled production build
npm test # Build, then run dist/lib.test.js with node --testConfiguring logging
The SDK emits a structured error-level log line when a handler returns a response that fails its buf.validate rules. The safety-net interceptor still produces a Code.Internal wire response, but first writes a line with the RPC method, response type, violations, and SDK version. Call validate(Schema, resp) inside the handler (see src/service.ts) if you want the failure raised on your own stack frame instead.
Default logger
If you do not pass a logger option to createService, the SDK uses:
const defaultLogger = {
error: (msg, fields) => console.error(JSON.stringify({ msg, ...fields })),
};Output goes to stderr as a single JSON line per event.
Plug in pino (or any other logger)
The SDK accepts any object with an error(msg, fields?) method. Adapter for pino:
import pino from "pino";
const pinoLogger = pino();
createService(networkPublicKeyHex, (r) => { /* ... */ }, {
logger: {
error: (msg, fields) => pinoLogger.error(fields, msg),
},
});Same shape works for winston, bunyan, or any custom transport — the SDK only needs error(msg, fields) to exist.
Deployment
docker build -t my-provider .
docker run -p 3000:3000 --env-file .env my-providerSDK Reference
For direct SDK usage (without the starter), see the TypeScript SDK documentation.
Troubleshooting
"Directory already exists" -- Choose a different project name.
"OpenSSL not found" -- Install OpenSSL (brew install openssl on macOS, sudo apt-get install openssl on Debian/Ubuntu).
Key generation fails -- Ensure OpenSSL is in your PATH: openssl version.
npm install fails -- Check Node.js >= 18 and npm >= 8: node --version && npm --version.
