HiveXPH SDKhivexph-sdk
NPM
Developer toolkit for Hive Custom JSON and Hive Engine transactions.

Payments

Payments and transfer triggers

A payment is not just money moving. It is an action request. The SDK carries the same standardized { action, metadata } payload inside the transfer memo, so a HIVE transfer and a Hive Engine token transfer trigger application logic exactly the same way.

The idea

Custom JSON operations already carry a standardized payload. Payments extend that same protocol to value transfers: the memo of a native HIVE/HBD transfer, and the memo of a Hive Engine tokens.transfer action, both hold the identical { action, metadata } object. Your application reads one shape, whichever network the money came from.

JSON
{
  "action": "purchase",
  "metadata": { "orderId": "A-1029", "sku": "pro-plan" }
}

One payload, many transports

Transports of the standardized payload
ParameterTypeRequiredDescription
custom_jsonjson fieldNoThe original transport — no value attached.
HIVE / HBD transfermemo fieldNoNative Layer 1 payment. Final as soon as the block is produced.
Hive Engine transfercontract memoNoLayer 2 payment inside a custom_json contract action. Execution must be verified.

The payments namespace

TypeScript
import { HiveClient } from "hivexph-sdk";

const hive = new HiveClient({
  accounts: { treasury: { accountEnv: "TREASURY_ACCOUNT", keyEnv: "TREASURY_ACTIVE_KEY" } },
});

// Native HIVE payment carrying a trigger
await hive.payments.hive.transfer({
  from: hive.accounts.treasury,
  account: "bob",
  amount: "10.000",
  symbol: "HIVE",
  action: "purchase",
  metadata: { orderId: "A-1029" },
});

// Hive Engine (Layer 2) payment carrying the same trigger
await hive.payments.engine.transfer({
  from: hive.accounts.treasury,
  account: "bob",
  symbol: "SWAP.HIVE",
  quantity: "10",
  action: "purchase",
  metadata: { orderId: "A-1029" },
});
hive.payments
ParameterTypeRequiredDescription
hiveHivePaymentClientNoNative HIVE / HBD transfers.
engineEnginePaymentClientNoHive Engine token transfers.
parse(input)Promise<ParsedPayment[]>NoEvery payment carried by a transaction id.
validate(input)Promise<PaymentValidationResult>NoExistence + execution + expectation checks.
watch(options)AsyncGenerator<ParsedPayment>NoLive payment detection as an async iterator over the core block stream.

Browser flows live under hive.keychain.payments.hive and hive.keychain.payments.engine. Native transfers use Keychain's dedicated transfer request; Layer 2 transfers are signed as active-authority custom_json.

Payment lifecycle

PaymentStatus
ParameterTypeRequiredDescription
pendingstatusNoExecution is not verifiable yet.
successstatusNoTransfer happened and, on Layer 2, the contract executed.
failedstatusNoThe transaction exists but the contract rejected it.
invalidstatusNoIt executed but does not match your expectations.
not_foundstatusNoNo payment for that id.

Important

A Hive Engine payment included in a Hive block has not necessarily succeeded. Layer 1 inclusion only proves the custom_json was broadcast — the sidechain can still reject it. Only validate() or the stream's execution check can report success: true.

Rules the SDK enforces

  • Amounts and quantities are decimal strings — never JavaScript numbers.
  • Native amounts are normalized to three decimals ("10" becomes "10.000 HIVE").
  • A malformed memo never throws in a stream: the trigger is simply null.
  • Payloads carry no timestamps — the blockchain is the clock.
  • The SDK is stateless: idempotency is your application's job, keyed on transactionId plus operationIndex.