npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

goatflow-sdk

v0.3.0

Published

TypeScript SDK for GOAT Flow payment integration

Readme

goatflow-sdk

Frontend TypeScript SDK for GOAT Flow, built on ethers v6. It provides:

  • PaymentHelper for buyer-authorized browser ERC-20 transfers
  • ERC20Token approval and transfer helpers
  • EIP-712 callback-signing utilities
  • MPPClient for challenge, buyer transfer, verification, and receipt recovery

This package does not hold merchant API credentials or create authenticated orders. Use goatflow-sdk-server or the Go server SDK on your backend. Buyer-wallet transfers go directly to the instructed recipient; GOAT Flow and this SDK do not act as an intermediary for merchant customer funds.

Install

npm install goatflow-sdk ethers

The package declares Node.js >= 18 for non-browser use.

Pay a server-created order

The server and browser SDK Order types are different. Your backend must map:

  • server fromChainId -> browser chainId
  • the create-order payer -> browser fromAddress
import { PaymentHelper, type Order } from 'goatflow-sdk'
import { ethers } from 'ethers'

const order: Order = await fetch('/api/orders', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ productId: 'mug' }),
}).then((response) => response.json())

const provider = new ethers.BrowserProvider(window.ethereum)
const signer = await provider.getSigner()

const network = await provider.getNetwork()
if (Number(network.chainId) !== order.chainId) {
  throw new Error(`Switch wallet to chain ${order.chainId}`)
}

const payer = await signer.getAddress()
if (payer.toLowerCase() !== order.fromAddress.toLowerCase()) {
  throw new Error('Connected wallet does not match the order payer')
}

if (Math.floor(Date.now() / 1000) >= order.expiresAt) {
  throw new Error('Order expired')
}

const payment = new PaymentHelper(signer)

if (order.calldataSignRequest) {
  throw new Error(
    'Use the operator-provisioned callback flow before paying this order',
  )
}

const result = await payment.pay(order)
if (!result.success) throw new Error(result.error ?? 'Payment failed')

This basic example covers DIRECT. In an explicitly operator-provisioned callback environment, map calldataSignRequest, sign its exact EIP-712 payload on the returned domain chain, submit it through the merchant backend, and switch back to the transfer source chain before paying. See the full integration guide.

PaymentHelper.pay() checks the token balance, sends transfer(order.payToAddress, order.amountWei), waits for a successful receipt, and returns a PaymentResult. The connected buyer signer sends tokens directly to the instructed recipient; the SDK does not hold, route, or disburse merchant customer funds. It catches transfer errors and returns { success: false, error }; it does not perform chain, payer, or expiry checks. It also does not classify TRANSACTION_REPLACED, so reconcile a wallet speed-up and backend order before retrying a result reported as failed.

All supported order flows still use a user-side ERC-20 transfer to payToAddress:

  • ERC20_DIRECT: merchant recipient
  • ERC20_3009: operator-provisioned compatibility recipient
  • ERC20_APPROVE_XFER: operator-provisioned compatibility recipient

DIRECT is the standard/default public path. The other values are retained for explicitly provisioned environments and are not part of public onboarding.

MPP

Machine Payments Protocol (MPP) is an independent open protocol. MPPClient implements GOAT Flow's current adapter, not the standard MPP HTTP Challenge/Credential/Receipt exchange. Its JSON challenge/verify endpoints and signed three-segment receipt are GOAT-specific, and this repository has no official-SDK interoperability test.

import { MPPClient, MPPError } from 'goatflow-sdk'

const mpp = new MPPClient({
  coreUrl: 'https://flow-api.goat.network', // must not end with "/"
  signer,
})

async function payForRoute() {
  try {
    return await mpp.pay({
      merchantId: 'merchant_123',
      routeCanonical: 'GET:api:data',
      onPhase: (phase) => console.log(phase),
    })
  } catch (error) {
    if (error instanceof MPPError && error.recoverable) {
      // The transfer was already broadcast. Resume verification; do not pay again.
      return mpp.verifyChallenge(error.recoverable)
    }
    throw error
  }
}

const result = await payForRoute()
await fetch('/api/data', {
  headers: { 'Payment-Receipt': result.receiptHeader },
})

This is the standalone GOAT Flow MPP adapter, so coreUrl is the Core/API origin configured for the deployment. QuickPay pay-mpp derives its adapter origin from the trusted QuickPay link instead. The returned challenge is authoritative for amount, chain, token, recipient, expiry, MAC, and pricing version.

Behavior verified by tests:

  • POST /mpp/v1/challenge: HTTP 402 is success
  • chain and challenge expiry are checked before broadcasting
  • payChallenge() returns { txHash, tx } without waiting locally for mining
  • POST /mpp/v1/verify: 202, 429, network errors, and eligible 5xx responses are retried with bounded backoff
  • successful verification requires the GOAT Flow profile's three-segment Payment-Receipt extension: base64url(JSON(receipt)).base64url(signature).algorithm
  • matching fee-bump replacements are followed
  • post-broadcast failures include MPPError.recoverable

Keep onPhase non-throwing or catch its errors locally; application callback errors can replace the SDK's expected MPPError.

For browser use, Core must allow the DApp origin and expose Payment-Receipt; the protected resource must allow that origin and the Payment-Receipt request header. Otherwise use a server-side buyer client.

ERC-20 approvals

PaymentHelper.approveToken, ERC20Token.setApproval, and ERC20Token.ensureApproval:

  • approve exact amounts by default; { unlimited: true } is explicit
  • avoid a transaction when the existing allowance already satisfies the request
  • probe non-zero allowance replacement with eth_call
  • use confirmed approve(0) only for USDT-style/no-simulation fallback
  • follow matching wallet fee-bump replacements
  • validate bigint range and option types before submitting a transaction

setApproval() returns { tx?, resetTx? }. PaymentHelper.approveToken() returns only the final tx (or undefined).

Exports

import {
  PaymentHelper,
  MPPClient,
  MPPError,
  PaymentError,
  ERC20Token,
  parseUnits,
  formatUnits,
  signTypedData,
  hashCalldata,
  verifySignature,
} from 'goatflow-sdk'

See the package integration guide, the repository integration guide, and the Changelog.

License

MIT