Skip to content

@pipsync/connector-kit

A small, stable TypeScript/JavaScript contract for turning already-received source payloads into deterministic PipSync signal envelopes.

The package contains:

  • a fail-closed SignalConnector interface
  • versioned SignalEnvelope types
  • a side-effect-free synthetic JSON reference connector
  • a reusable conformance harness
  • an in-memory PaperSink that emits only deterministic PAPER-… receipt IDs

It contains no HTTP, WebSocket, broker, credential, environment-variable, database, or live-order integration.

Important

This kit normalizes data; it does not authenticate a sender. Verify the exact raw request body and transport-specific credentials before parsing or passing a payload to a connector. Trading involves risk. This package is developer tooling, not financial advice or a guarantee of execution or returns.

Requirements

  • Node.js 20 or newer
  • TypeScript is optional for consumers; compiled JavaScript and declarations are published together

Install

The first npm registry release has not been published yet. The current supported path is to build and pack the audited GitHub source:

git clone https://github.com/pipsyncio/pipsync-connector-kit.git
cd pipsync-connector-kit
npm ci
npm test
npm pack

Install the generated .tgz file into another local project:

npm install /path/to/pipsync-connector-kit/pipsync-connector-kit-1.0.0.tgz

After the first npm registry publication, the shorter registry command will be:

npm install @pipsync/connector-kit

Do not interpret that future command as evidence that the package is already present in npm. All repository tests are local and use synthetic data. No credentials or network service are required.

TypeScript quick start

import { PaperSink, SyntheticJsonConnector } from "@pipsync/connector-kit";

const connector = new SyntheticJsonConnector();
const result = connector.normalize(
  {
    messageId: "synthetic-message-001",
    symbol: "EUR/USD",
    side: "long",
    entryPrice: "1.0850",
    stopLoss: "1.0820",
    takeProfits: ["1.0900"]
  },
  { receivedAt: "2026-01-15T10:30:00Z" }
);

if (!result.ok) {
  console.error(result.error.code);
} else {
  const paper = new PaperSink();
  console.log(paper.submit(result.envelope));
}

JavaScript uses the same ESM imports and return-value checks; the public API does not rely on TypeScript-only runtime behavior.

Connector boundary

A connector receives an unknown payload plus an explicit deterministic context and returns one of two values:

type NormalizationResult =
  | { ok: true; envelope: SignalEnvelope }
  | { ok: false; error: NormalizationError };

Missing or invalid instrument and direction always produce an error. A connector must never fill them from guesses, route an incomplete signal, read a credential, fetch remote data, persist an event, or execute an order.

The reference connector accepts JSON objects or JSON object strings with these synthetic aliases:

  • instrument or symbol
  • direction or side
  • BUY, LONG, or BULLISHBUY
  • SELL, SHORT, or BEARISHSELL
  • optional messageId, occurredAt, entryPrice, stopLoss, and takeProfits

When both a canonical field and its alias are present, they must normalize to the same value; conflicting instrument/symbol or direction/side values fail closed. Unknown source-input fields are ignored and never copied into the normalized envelope. The conformance harness enforces exact property allowlists for envelopes, nested source, results, errors, and adapter metadata; unsupported output properties such as rawPayload are rejected. Errors contain stable codes, not raw payload content.

Relationship to pipsync.signal.v1

SignalEnvelope and the standalone pipsync.signal.v1 interchange object are intentionally separate contracts:

Contract Purpose
pipsync.signal-envelope.v1 normalization-stage identity, source, occurrence time, and deterministic idempotency
pipsync.signal.v1 public synthetic interchange object used by specs, SDKs, mocks, and conformance tooling; it does not define a live ingestion endpoint

Use the explicit fail-closed adapter when crossing that boundary:

import { toPipsyncSignalV1 } from "@pipsync/connector-kit";

if (!result.ok) throw new Error(result.error.code);
const adapted = toPipsyncSignalV1(result.envelope, {
  id: "123e4567-e89b-12d3-a456-426614174000",
  channelName: "Synthetic channel"
});

if (!adapted.ok) {
  console.error(adapted.error.code);
} else {
  console.log(adapted.signal.schemaVersion); // pipsync.signal.v1
}

The adapter requires entryPrice, a caller-supplied UUID, and channelName, enforces the standalone schema limits, and never copies source, idempotencyKey, occurredAt, or unknown fields. Missing required data returns an error instead of a guessed default.

Deterministic idempotency

The envelope idempotency key is a SHA-256 digest scoped by connector ID:

  1. When an authenticated, durable source messageId exists, identity is connectorId + messageId.
  2. Otherwise, identity is connectorId + normalized signal content + occurredAt.

No timestamp, random value, or mutable delivery status is generated internally. The caller supplies receivedAt, and repeated normalization of the same occurrence produces the same key across processes.

The fallback prevents exact duplicate occurrences; it cannot infer whether two intentionally repeated signals are distinct. Source connectors should prefer a durable provider event/message ID. A production host still needs an atomic unique constraint or equivalent claim scoped by tenant, endpoint, and environment before side effects. PaperSink's in-memory map is same-process test support, not durable deduplication evidence.

Conformance

Connector authors can run the exported test harness with synthetic cases:

import {
  assertConnectorConformance,
  SyntheticJsonConnector,
  type ConnectorConformanceCase
} from "@pipsync/connector-kit";

const cases: ConnectorConformanceCase[] = [
  {
    kind: "valid",
    name: "normalizes a buy",
    input: {
      messageId: "fixture-1",
      instrument: "EURUSD",
      direction: "BUY"
    },
    context: { receivedAt: "2026-01-15T10:30:00Z" },
    expected: { instrument: "EURUSD", direction: "BUY" }
  },
  {
    kind: "invalid",
    name: "rejects a missing instrument",
    input: { direction: "BUY" },
    context: { receivedAt: "2026-01-15T10:30:00Z" },
    expectedErrorCode: "INSTRUMENT_REQUIRED"
  }
];

await assertConnectorConformance(new SyntheticJsonConnector(), cases);

The harness checks exact descriptor/result/envelope shapes, input immutability, repeat determinism, semantic idempotency, cross-case identity uniqueness, exact expected fields, and fail-closed error codes. Passing it does not prove sender authenticity, durable replay protection, production safety, or broker compatibility.

Governance levels

Level Meaning
verified A version-specific connector release reviewed and designated by PipSync maintainers against the published checklist
community Community-owned, named maintainers, passing conformance; not reviewed or endorsed by PipSync
experimental Prototype contract that may change and must not be enabled by default

See GOVERNANCE.md for promotion, revocation, naming, and claim rules and VERIFIED_RELEASES.md for version-specific records. A governance label never means profitable, risk-free, live-ready, independently security-certified, or certified by a broker/provider.

Security model

  • authenticate before parsing or trusted persistence
  • use authenticated provider identity for idempotency when available
  • atomically claim idempotency before any downstream side effect
  • retain immutable receipt history for retry/replay outside this package
  • keep raw payloads, tokens, signatures, customer data, and account identifiers out of errors and fixtures
  • keep live execution in a separate, explicit, independently reviewed adapter

Report vulnerabilities privately as described in SECURITY.md.

Continue with PipSync

The kit proves a connector's normalization contract, not hosted compatibility. For supported source and broker combinations, use the PipSync integration directory.

License

Apache-2.0. See LICENSE.

About

Source connector contract, conformance suite, and in-memory paper sink.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages