diff --git a/packages/ilp-packet/index.ts b/packages/ilp-packet/index.ts index 265321b7..465d16f9 100644 --- a/packages/ilp-packet/index.ts +++ b/packages/ilp-packet/index.ts @@ -9,6 +9,8 @@ import { stringToTwoNumbers, twoNumbersToString } from './src/utils/uint64' import Long = require('long') import * as assert from 'assert' +export const Errors = require('./src/errors') + export enum Type { TYPE_ILP_PAYMENT = 1, TYPE_ILQP_LIQUIDITY_REQUEST = 2, @@ -26,6 +28,21 @@ export enum Type { TYPE_ILP_REJECT = 14 } +export interface IlpErrorClass { + message: string, + ilpErrorCode?: string, + ilpData?: Buffer +} + +export const errorToReject = (address: string, error: IlpErrorClass) => { + return serializeIlpReject({ + code: error.ilpErrorCode || 'F00', + triggeredBy: address, + message: error.message || '', + data: error.ilpData || Buffer.alloc(0) + }) +} + export const serializeEnvelope = (type: number, contents: Buffer) => { const writer = new Writer() writer.writeUInt8(type) diff --git a/packages/ilp-packet/src/errors.ts b/packages/ilp-packet/src/errors.ts new file mode 100644 index 00000000..0e82c6f7 --- /dev/null +++ b/packages/ilp-packet/src/errors.ts @@ -0,0 +1,213 @@ +import { Writer } from 'oer-utils' +import { stringToTwoNumbers, twoNumbersToString } from './utils/uint64' +import BaseError = require('extensible-error') + +export const codes = { + F00_BAD_REQUEST: 'F00', + F01_INVALID_PACKET: 'F01', + F02_UNREACHABLE: 'F02', + F03_INVALID_AMOUNT: 'F03', + F04_INSUFFICIENT_DESTINATION_AMOUNT: 'F04', + F05_WRONG_CONDITION: 'F05', + F06_UNEXPECTED_PAYMENT: 'F06', + F07_CANNOT_RECEIVE: 'F07', + F08_AMOUNT_TOO_LARGE: 'F08', + F99_APPLICATION_ERROR: 'F99', + T00_INTERNAL_ERROR: 'T00', + T01_PEER_UNREACHABLE: 'T01', + T02_PEER_BUSY: 'T02', + T03_CONNECTOR_BUSY: 'T03', + T04_INSUFFICIENT_LIQUIDITY: 'T04', + T05_RATE_LIMITED: 'T05', + T99_APPLICATION_ERROR: 'T99', + R00_TRANSFER_TIMED_OUT: 'R00', + R01_INSUFFICIENT_SOURCE_AMOUNT: 'R01', + R02_INSUFFICIENT_TIMEOUT: 'R02', + R99_APPLICATION_ERROR: 'R99' +} + +export class BadRequestError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.F00_BAD_REQUEST + } +} + +export class InvalidPacketError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.F01_INVALID_PACKET + } +} + +export class UnreachableError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.F02_UNREACHABLE + } +} + +export class InvalidAmountError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.F03_INVALID_AMOUNT + } +} + +export class InsufficientDestinationAmountError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.F04_INSUFFICIENT_DESTINATION_AMOUNT + } +} + +export class WrongConditionError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.F05_WRONG_CONDITION + } +} + +export class UnexpectedPaymentError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.F06_UNEXPECTED_PAYMENT + } +} + +export class CannotReceiveError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.F07_CANNOT_RECEIVE + } +} + +export interface AmountTooLargeErrorOpts { + receivedAmount: string, + maximumAmount: string +} + +export class AmountTooLargeError extends BaseError { + public ilpErrorCode: string + public ilpData: Buffer + constructor (message: string, opts: AmountTooLargeErrorOpts) { + super(message) + this.ilpErrorCode = codes.F08_AMOUNT_TOO_LARGE + + const writer = new Writer() + writer.writeUInt64(stringToTwoNumbers(opts.receivedAmount)) + writer.writeUInt64(stringToTwoNumbers(opts.maximumAmount)) + + this.ilpData = writer.getBuffer() + } +} + +export class FinalApplicationError extends BaseError { + public ilpErrorCode: string + public ilpData: Buffer + constructor (message: string, data: Buffer) { + super(message) + this.ilpErrorCode = codes.F99_APPLICATION_ERROR + this.ilpData = data + } +} + +export class InternalError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.T00_INTERNAL_ERROR + } +} + +export class PeerUnreachableError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.T01_PEER_UNREACHABLE + } +} + +export class PeerBusyError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.T02_PEER_BUSY + } +} + +export class ConnectorBusyError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.T03_CONNECTOR_BUSY + } +} + +export class InsufficientLiquidityError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.T04_INSUFFICIENT_LIQUIDITY + } +} + +export class RateLimitedError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.T05_RATE_LIMITED + } +} + +export class TemporaryApplicationError extends BaseError { + public ilpErrorCode: string + public ilpData: Buffer + constructor (message: string, data: Buffer) { + super(message) + this.ilpErrorCode = codes.T99_APPLICATION_ERROR + this.ilpData = data + } +} + +export class TransferTimedOutError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.R00_TRANSFER_TIMED_OUT + } +} + +export class InsufficientSourceAmountError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.R01_INSUFFICIENT_SOURCE_AMOUNT + } +} + +export class InsufficientTimeoutError extends BaseError { + public ilpErrorCode: string + constructor (message: string) { + super(message) + this.ilpErrorCode = codes.R02_INSUFFICIENT_TIMEOUT + } +} + +export class RelativeApplicationError extends BaseError { + public ilpErrorCode: string + public ilpData: Buffer + constructor (message: string, data: Buffer) { + super(message) + this.ilpErrorCode = codes.R99_APPLICATION_ERROR + this.ilpData = data + } +}