connext
Advanced tools
Comparing version 3.0.10 to 3.0.11
@@ -24,2 +24,3 @@ import { WithdrawalParameters, ChannelManagerChannelDetails, Sync, ThreadState, ThreadStateUpdate, HubConfig } from './types'; | ||
import ThreadsController from './controllers/ThreadsController'; | ||
import { RedeemController } from './controllers/RedeemController'; | ||
declare type Address = string; | ||
@@ -70,2 +71,3 @@ /********************************* | ||
config(): Promise<HubConfig>; | ||
redeem(secret: string): Promise<PurchasePaymentHubResponse>; | ||
} | ||
@@ -194,2 +196,5 @@ export declare abstract class IWeb3TxWrapper { | ||
requestCollateral(): Promise<void>; | ||
redeem(secret: string): Promise<{ | ||
purchaseId: string; | ||
}>; | ||
} | ||
@@ -214,2 +219,3 @@ /** | ||
threadsController: ThreadsController; | ||
redeemController: RedeemController; | ||
constructor(opts: ConnextClientOptions); | ||
@@ -222,2 +228,3 @@ private getControllers; | ||
dispatch(action: Action): void; | ||
generateSecret(): string; | ||
sign(hash: string, user: string): Promise<any>; | ||
@@ -224,0 +231,0 @@ signChannelState(state: UnsignedChannelState): Promise<ChannelState>; |
@@ -12,5 +12,6 @@ "use strict"; | ||
const types_1 = require("./types"); | ||
const actions = require("./state/actions"); | ||
const redux_1 = require("redux"); | ||
require('dotenv').config(); | ||
const events_1 = require("events"); | ||
const Web3 = require("web3"); | ||
const ChannelManagerAbi_1 = require("./contract/ChannelManagerAbi"); | ||
@@ -33,6 +34,5 @@ const networking_1 = require("./helpers/networking"); | ||
const CollateralController_1 = require("./controllers/CollateralController"); | ||
const actions = require("./state/actions"); | ||
const ThreadsController_1 = require("./controllers/ThreadsController"); | ||
const RedeemController_1 = require("./controllers/RedeemController"); | ||
class HubAPIClient { | ||
// private tokenName?: string | ||
constructor(user, networking, tokenName) { | ||
@@ -78,3 +78,2 @@ // post to hub telling user wants to deposit | ||
this.networking = networking; | ||
// this.tokenName = tokenName | ||
} | ||
@@ -264,2 +263,17 @@ config() { | ||
} | ||
redeem(secret) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const response = yield this.networking.post(`payments/redeem/${this.user}`, { secret }); | ||
return response.data; | ||
} | ||
catch (e) { | ||
console.log(e.message); | ||
if (e.message.indexOf("Payment has been redeemed.") != -1) { | ||
throw new Error(`Payment has been redeemed.`); | ||
} | ||
throw e; | ||
} | ||
}); | ||
} | ||
requestExchange(weiToSell, tokensToSell, txCountGlobal) { | ||
@@ -603,2 +617,7 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
redeem(secret) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return yield this.internal.redeemController.redeem(secret); | ||
}); | ||
} | ||
} | ||
@@ -638,2 +657,3 @@ exports.ConnextClient = ConnextClient; | ||
this.threadsController = new ThreadsController_1.default('ThreadsController', this); | ||
this.redeemController = new RedeemController_1.RedeemController('RedeemController', this); | ||
} | ||
@@ -757,2 +777,7 @@ getControllers() { | ||
} | ||
generateSecret() { | ||
return Web3.utils.soliditySha3({ | ||
type: 'bytes32', value: Web3.utils.randomHex(32) | ||
}); | ||
} | ||
sign(hash, user) { | ||
@@ -759,0 +784,0 @@ return __awaiter(this, void 0, void 0, function* () { |
@@ -13,2 +13,4 @@ "use strict"; | ||
const getChannel_1 = require("../lib/getChannel"); | ||
const utils_1 = require("../lib/utils"); | ||
const Utils_1 = require("../Utils"); | ||
// **********************************************// | ||
@@ -49,30 +51,50 @@ // | ||
let newChannelState = null; | ||
if (payment.type == 'PT_THREAD') { | ||
// Create a new thread for the payment value | ||
const { thread, channel } = yield this.connext.threadsController.openThread(payment.recipient, payment.amount); | ||
// wait for thread to be added to local store and channel | ||
// state/connext persistent state to be updated | ||
// TODO: figure out if this will wait for the channel state to | ||
// be updated via state update controller (should) | ||
// await this.connext.awaitPersistentStateSaved() | ||
// add thread payment to signed payments | ||
const state = yield this.connext.signThreadState(this.validator.generateThreadPayment(thread, payment.amount)); | ||
// TODO: make sure the state update controller is able to update | ||
// the state of the active thread once the payment is made | ||
signedPayments.push(Object.assign({}, payment, { type: "PT_THREAD", update: { state } })); | ||
// update new channel state | ||
newChannelState = channel; | ||
// TODO: what happens if you have multiple thread payments | ||
// before your thread can be closed? (eg embedded payments) | ||
// PUNT on this -- AB | ||
switch (payment.type) { | ||
case 'PT_THREAD': | ||
// Create a new thread for the payment value | ||
const { thread, channel } = yield this.connext.threadsController.openThread(payment.recipient, payment.amount); | ||
// add thread payment to signed payments | ||
const state = yield this.connext.signThreadState(this.validator.generateThreadPayment(thread, payment.amount)); | ||
signedPayments.push(Object.assign({}, payment, { type: "PT_THREAD", update: { state } })); | ||
// update new channel state | ||
newChannelState = channel; | ||
// TODO: what happens if you have multiple thread payments | ||
// before your thread can be closed? (eg embedded payments) | ||
// PUNT on this -- AB | ||
break; | ||
case 'PT_CHANNEL': | ||
const chanArgs = Object.assign({ recipient: 'hub' }, payment.amount); | ||
newChannelState = yield this.connext.signChannelState(this.validator.generateChannelPayment(curChannelState, chanArgs)); | ||
signedPayments.push(Object.assign({}, payment, { type: 'PT_CHANNEL', update: { | ||
reason: 'Payment', | ||
args: chanArgs, | ||
sigUser: newChannelState.sigUser, | ||
txCount: newChannelState.txCountGlobal, | ||
} })); | ||
break; | ||
case 'PT_LINK': | ||
// the pt link payment type has 2 cases | ||
// 1. User is the sender, in which case it should | ||
// be handled like normal channel updates | ||
// 2. User is the redeemer, in which case the response | ||
// should be handled via the 'RedeemController', | ||
// where the user posts to a separate endpoint (not buy) | ||
// check that a secret exists | ||
if (!payment.secret) { | ||
throw new Error(`Secret is not present on linked payment, aborting purchase. Purchase: ${JSON.stringify(purchase, null, 2)}`); | ||
} | ||
const linkArgs = Object.assign({ recipient: 'hub' }, payment.amount); | ||
newChannelState = yield this.connext.signChannelState(this.validator.generateChannelPayment(curChannelState, linkArgs)); | ||
signedPayments.push(Object.assign({}, payment, { type: 'PT_LINK', recipient: Utils_1.emptyAddress, update: { | ||
reason: 'Payment', | ||
args: linkArgs, | ||
sigUser: newChannelState.sigUser, | ||
txCount: newChannelState.txCountGlobal, | ||
} })); | ||
break; | ||
default: | ||
utils_1.assertUnreachable(payment.type); | ||
} | ||
else { // handle channel payments | ||
const args = Object.assign({ recipient: 'hub' }, payment.amount); | ||
newChannelState = yield this.connext.signChannelState(this.validator.generateChannelPayment(curChannelState, args)); | ||
signedPayments.push(Object.assign({}, payment, { type: 'PT_CHANNEL', update: { | ||
reason: 'Payment', | ||
args: args, | ||
sigUser: newChannelState.sigUser, | ||
txCount: newChannelState.txCountGlobal, | ||
} })); | ||
if (!newChannelState) { | ||
throw new Error(`We should never get here. Something has gone wrong with 'assertUnreachable'. Buy controller could not generate new channel state.`); | ||
} | ||
@@ -79,0 +101,0 @@ curChannelState = newChannelState; |
@@ -37,3 +37,10 @@ "use strict"; | ||
if (res.status < 200 || res.status > 299) { | ||
throw exports.errorResponse(res.status, res.body, `Received non-200 response: ${res.status}`); | ||
let text; | ||
try { | ||
text = yield res.text(); | ||
} | ||
catch (e) { | ||
text = res.statusText; | ||
} | ||
throw exports.errorResponse(res.status, res.body, `Received non-200 response: ${text}`); | ||
} | ||
@@ -40,0 +47,0 @@ if (res.status === 204) { |
@@ -52,2 +52,3 @@ import { IWeb3TxWrapper } from '../Connext'; | ||
config(): Promise<HubConfig>; | ||
redeem(secret: string): Promise<PurchasePaymentHubResponse>; | ||
getChannel(): Promise<ChannelRow>; | ||
@@ -54,0 +55,0 @@ getActiveThreads(): Promise<ThreadState[]>; |
@@ -204,2 +204,27 @@ "use strict"; | ||
} | ||
redeem(secret) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// NOTE: by default assumes this is redeemers first payment | ||
// if this is not what you are testing against, must use | ||
// the patch functions in test | ||
return { | ||
purchaseId: 'async-payment-bb', | ||
sync: { status: "CS_OPEN", | ||
updates: [{ | ||
type: 'channel', | ||
update: { | ||
reason: 'ProposePendingDeposit', | ||
createdOn: new Date(), | ||
args: _3.getDepositArgs('full', { | ||
depositToken: [0, 1], | ||
depositWei: [0, 0], | ||
}), | ||
sigHub: _1.mkHash('0x51512'), | ||
sigUser: '', | ||
txCount: 1, | ||
}, | ||
}] } | ||
}; | ||
}); | ||
} | ||
getChannel() { | ||
@@ -263,3 +288,3 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
if (p.type == 'PT_CHANNEL') { | ||
if (p.type == 'PT_CHANNEL' || 'PT_LINK') { | ||
return { | ||
@@ -280,3 +305,7 @@ type: 'channel', | ||
type: 'thread', | ||
update: { state: p.update.state, id: p.update.state.threadId, createdOn: new Date() } | ||
update: { | ||
state: p.update.state, | ||
id: p.update.state.threadId, | ||
createdOn: new Date() | ||
} | ||
}; | ||
@@ -283,0 +312,0 @@ } |
@@ -226,3 +226,3 @@ import BN = require('bn.js'); | ||
export declare type EmptyChannelArgs = ConfirmPendingArgs; | ||
export declare type ArgsTypes<T = string> = ExchangeArgs<T> | PaymentArgs<T> | DepositArgs<T> | WithdrawalArgs<T> | UnsignedThreadState<T> | ConfirmPendingArgs | InvalidationArgs | EmptyChannelArgs | ThreadState<T> | {}; | ||
export declare type ArgsTypes<T = string> = ExchangeArgs<T> | PaymentArgs<T> | DepositArgs<T> | WithdrawalArgs<T> | ConfirmPendingArgs | InvalidationArgs | EmptyChannelArgs | ThreadState<T> | {}; | ||
export declare type ArgTypesBN = ArgsTypes<BN>; | ||
@@ -238,3 +238,3 @@ export declare type ArgTypesBigNumber = ArgsTypes<BigNumber>; | ||
createdOn?: Date; | ||
initialThreadStates?: UnsignedThreadState[]; | ||
initialThreadStates?: ThreadState[]; | ||
}; | ||
@@ -427,6 +427,6 @@ export declare type UpdateRequestTypes<T = string> = { | ||
export declare type WithdrawalParametersBigNumber = WithdrawalParameters<BigNumber>; | ||
export declare const withdrawalParamsNumericFields: string[]; | ||
/********************************* | ||
******* TYPE CONVERSIONS ******** | ||
*********************************/ | ||
export declare const withdrawalParamsNumericFields: string[]; | ||
export declare function channelUpdateToUpdateRequest(up: ChannelStateUpdate): UpdateRequest; | ||
@@ -458,2 +458,3 @@ export declare const channelNumericFields: string[]; | ||
export declare function convertWithdrawal<To extends NumericTypeName>(to: To, obj: WithdrawalArgs<any>): WithdrawalArgs<NumericTypes[To]>; | ||
export declare function convertWithdrawalParams<To extends NumericTypeName>(to: To, obj: WithdrawalParameters<any>): WithdrawalParameters<NumericTypes[To]>; | ||
export declare const proposePendingNumericArgs: string[]; | ||
@@ -467,3 +468,3 @@ export declare function convertProposePending<To extends NumericTypeName>(to: To, obj: PendingArgs<any>): PendingArgs<NumericTypes[To]>; | ||
*********************************/ | ||
export declare type PurchasePaymentType = 'PT_CHANNEL' | 'PT_THREAD'; | ||
export declare type PurchasePaymentType = 'PT_CHANNEL' | 'PT_THREAD' | 'PT_LINK'; | ||
export interface PurchaseRequest<MetadataType = any, PaymentMetadataType = any> { | ||
@@ -482,2 +483,3 @@ meta: MetadataType; | ||
recipient: string; | ||
secret?: string; | ||
amount: Payment; | ||
@@ -491,2 +493,5 @@ meta: MetadataType; | ||
update: ThreadStateUpdate; | ||
} | { | ||
type: 'PT_LINK'; | ||
update: UpdateRequest<string, PaymentArgs>; | ||
})); | ||
@@ -493,0 +498,0 @@ export declare type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; |
@@ -243,2 +243,5 @@ "use strict"; | ||
exports.convertVerboseEvent = convertVerboseEvent; | ||
/********************************* | ||
******* TYPE CONVERSIONS ******** | ||
*********************************/ | ||
exports.withdrawalParamsNumericFields = [ | ||
@@ -250,5 +253,2 @@ 'withdrawalWeiUser', | ||
]; | ||
/********************************* | ||
******* TYPE CONVERSIONS ******** | ||
*********************************/ | ||
function channelUpdateToUpdateRequest(up) { | ||
@@ -373,2 +373,7 @@ return { | ||
exports.convertWithdrawal = convertWithdrawal; | ||
function convertWithdrawalParams(to, obj) { | ||
const fromType = getType(obj.tokensToSell); | ||
return convertFields(fromType, to, exports.withdrawalParamsNumericFields, obj); | ||
} | ||
exports.convertWithdrawalParams = convertWithdrawalParams; | ||
exports.proposePendingNumericArgs = [ | ||
@@ -375,0 +380,0 @@ 'depositWeiUser', |
@@ -31,5 +31,5 @@ import { InvalidationArgs, EmptyChannelArgs, SignedDepositRequestProposal } from './types'; | ||
confirmPending(prev: ChannelStateBN, args: ConfirmPendingArgs): Promise<string | null>; | ||
generateConfirmPending(prevStr: ChannelState, args: ConfirmPendingArgs): Promise<UnsignedChannelState>; | ||
emptyChannel(prev: ChannelStateBN, args: EmptyChannelArgs): Promise<string | null>; | ||
generateEmptyChannel(prevStr: ChannelState, args: EmptyChannelArgs): Promise<UnsignedChannelState>; | ||
generateConfirmPending(prevStr: ChannelState, args: ConfirmPendingArgs): Promise<UnsignedChannelState>; | ||
invalidation(latestValidState: ChannelStateBN, args: InvalidationArgs): string | null; | ||
@@ -50,3 +50,4 @@ generateInvalidation(prevStr: ChannelState, argsStr: InvalidationArgs): UnsignedChannelState<string>; | ||
assertDepositRequestSigner(req: SignedDepositRequestProposal, signer: Address): void; | ||
private cantAffordFromBalance; | ||
cantAffordFromBalance(state: ChannelStateBN, value: Partial<PaymentBN>, payor: "hub" | "user", currency?: "token" | "wei"): string | null; | ||
cantAffordFromBalance(state: ThreadStateBN, value: Partial<PaymentBN>, payor: "sender", currency?: "token" | "wei"): string | null; | ||
private conditions; | ||
@@ -53,0 +54,0 @@ private evaluateCondition; |
@@ -197,2 +197,18 @@ "use strict"; | ||
} | ||
// ensure the deposit is correctly signed by user if the sig user | ||
// exists | ||
if (args.sigUser) { | ||
try { | ||
const argsStr = types_2.convertDeposit("str", args); | ||
const proposal = { | ||
amountToken: argsStr.depositTokenUser, | ||
amountWei: argsStr.depositWeiUser, | ||
sigUser: args.sigUser, | ||
}; | ||
this.assertDepositRequestSigner(proposal, prev.user); | ||
} | ||
catch (e) { | ||
return `Invalid signer detected. ` + e.message + ` (prev: ${this.logChannel(prev)}, args: ${this.logArgs(args, "ProposePendingDeposit")}`; | ||
} | ||
} | ||
return null; | ||
@@ -253,2 +269,12 @@ } | ||
} | ||
generateConfirmPending(prevStr, args) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const prev = types_2.convertChannelState("bn", prevStr); | ||
const error = yield this.confirmPending(prev, args); | ||
if (error) { | ||
throw new Error(error); | ||
} | ||
return this.stateGenerator.confirmPending(prev); | ||
}); | ||
} | ||
emptyChannel(prev, args) { | ||
@@ -323,12 +349,2 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
generateConfirmPending(prevStr, args) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const prev = types_2.convertChannelState("bn", prevStr); | ||
const error = yield this.confirmPending(prev, args); | ||
if (error) { | ||
throw new Error(error); | ||
} | ||
return this.stateGenerator.confirmPending(prev); | ||
}); | ||
} | ||
// NOTE: the prev here is NOT the previous state in the state-chain | ||
@@ -335,0 +351,0 @@ // of events. Instead it is the previously "valid" update, meaning the |
{ | ||
"name": "connext", | ||
"description": "Shared code between wallet and hub", | ||
"version": "3.0.10", | ||
"version": "3.0.11", | ||
"main": "dist", | ||
@@ -6,0 +6,0 @@ "devDependencies": { |
@@ -1,7 +0,7 @@ | ||
import { WithdrawalParameters, ChannelManagerChannelDetails, Sync, ThreadState, addSigToThreadState, ThreadStateUpdate, channelUpdateToUpdateRequest, ThreadHistoryItem, HubConfig } from './types' | ||
import { WithdrawalParameters, ChannelManagerChannelDetails, Sync, ThreadState, addSigToThreadState, ThreadStateUpdate, channelUpdateToUpdateRequest, ThreadHistoryItem, HubConfig, SyncResult } from './types' | ||
import { DepositArgs, SignedDepositRequestProposal, Omit } from './types' | ||
import * as actions from './state/actions' | ||
import { PurchaseRequest } from './types' | ||
import { UpdateRequest } from './types' | ||
import { createStore, Action, applyMiddleware } from 'redux' | ||
require('dotenv').config() | ||
import { EventEmitter } from 'events' | ||
@@ -27,3 +27,2 @@ import Web3 = require('web3') | ||
addSigToChannelState, | ||
SyncResult, | ||
ChannelRow, | ||
@@ -41,12 +40,11 @@ ThreadRow, | ||
import { isFunction, ResolveablePromise, timeoutPromise } from "./lib/utils"; | ||
import { toBN, mul } from './helpers/bn' | ||
import { toBN } from './helpers/bn' | ||
import { ExchangeController } from './controllers/ExchangeController' | ||
import { ExchangeRates } from './state/ConnextState/ExchangeRates' | ||
import CollateralController from "./controllers/CollateralController"; | ||
import * as actions from './state/actions'; | ||
import { AbstractController } from './controllers/AbstractController' | ||
import { EventLog } from 'web3/types'; | ||
import { getChannel } from './lib/getChannel'; | ||
import ThreadsController from './controllers/ThreadsController'; | ||
import { getLastThreadUpdateId } from './lib/getLastThreadUpdateId'; | ||
import { RedeemController } from './controllers/RedeemController'; | ||
@@ -105,2 +103,3 @@ type Address = string | ||
config(): Promise<HubConfig> | ||
redeem(secret: string): Promise<PurchasePaymentHubResponse> | ||
} | ||
@@ -111,3 +110,2 @@ | ||
private networking: Networking | ||
// private tokenName?: string | ||
@@ -117,3 +115,2 @@ constructor(user: Address, networking: Networking, tokenName?: string) { | ||
this.networking = networking | ||
// this.tokenName = tokenName | ||
} | ||
@@ -309,2 +306,19 @@ | ||
async redeem(secret: string): Promise<PurchasePaymentHubResponse> { | ||
try { | ||
const response = await this.networking.post( | ||
`payments/redeem/${this.user}`, | ||
{ secret }, | ||
) | ||
return response.data | ||
} catch (e) { | ||
console.log(e.message) | ||
if (e.message.indexOf("Payment has been redeemed.") != -1) { | ||
throw new Error(`Payment has been redeemed.`) | ||
} | ||
throw e | ||
} | ||
} | ||
// post to hub telling user wants to deposit | ||
@@ -861,2 +875,6 @@ requestDeposit = async ( | ||
} | ||
async redeem(secret: string): Promise<{ purchaseId: string }> { | ||
return await this.internal.redeemController.redeem(secret) | ||
} | ||
} | ||
@@ -884,2 +902,3 @@ | ||
threadsController: ThreadsController | ||
redeemController: RedeemController | ||
@@ -919,2 +938,3 @@ constructor(opts: ConnextClientOptions) { | ||
this.threadsController = new ThreadsController('ThreadsController', this) | ||
this.redeemController = new RedeemController('RedeemController', this) | ||
} | ||
@@ -1042,2 +1062,8 @@ | ||
generateSecret(): string { | ||
return Web3.utils.soliditySha3({ | ||
type: 'bytes32', value: Web3.utils.randomHex(32) | ||
}) | ||
} | ||
async sign(hash: string, user: string) { | ||
@@ -1044,0 +1070,0 @@ return await ( |
import { assert, } from '../testing/index'; | ||
import { MockConnextInternal } from '@src/testing/mocks'; | ||
import { MockConnextInternal } from '../testing/mocks'; | ||
import { AbstractController } from './AbstractController'; | ||
@@ -4,0 +4,0 @@ // @ts-ignore |
import { MockConnextInternal, MockStore } from '../testing/mocks' | ||
import { assert, mkHash } from '../testing/index' | ||
import { PaymentArgs, } from '@src/types' | ||
// @ts-ignore | ||
@@ -5,0 +3,0 @@ global.fetch = require('node-fetch-polyfill'); |
@@ -1,6 +0,6 @@ | ||
import { PurchaseRequest, PurchasePayment, PaymentArgs, SyncResult, convertThreadState, convertPayment, ChannelState, ThreadHistoryItem } from '../types' | ||
import { PurchaseRequest, PurchasePayment, PaymentArgs, } from '../types' | ||
import { AbstractController } from './AbstractController' | ||
import { getChannel } from '../lib/getChannel' | ||
import { getActiveThreads } from '../lib/getActiveThreads'; | ||
import { toBN } from '../helpers/bn'; | ||
import { assertUnreachable } from '../lib/utils'; | ||
import { emptyAddress } from '../Utils'; | ||
@@ -45,59 +45,96 @@ // **********************************************// | ||
let newChannelState = null | ||
if (payment.type == 'PT_THREAD') { | ||
// Create a new thread for the payment value | ||
const { thread, channel } = await this.connext.threadsController.openThread( | ||
payment.recipient, | ||
payment.amount | ||
) | ||
switch (payment.type) { | ||
case 'PT_THREAD': | ||
// Create a new thread for the payment value | ||
const { thread, channel } = await this.connext.threadsController.openThread( | ||
payment.recipient, | ||
payment.amount | ||
) | ||
// wait for thread to be added to local store and channel | ||
// state/connext persistent state to be updated | ||
// TODO: figure out if this will wait for the channel state to | ||
// be updated via state update controller (should) | ||
// await this.connext.awaitPersistentStateSaved() | ||
// add thread payment to signed payments | ||
const state = await this.connext.signThreadState( | ||
this.validator.generateThreadPayment(thread, payment.amount) | ||
) | ||
// add thread payment to signed payments | ||
const state = await this.connext.signThreadState( | ||
this.validator.generateThreadPayment(thread, payment.amount) | ||
) | ||
signedPayments.push({ | ||
...payment, | ||
type: "PT_THREAD", | ||
update: { state } | ||
}) | ||
// TODO: make sure the state update controller is able to update | ||
// the state of the active thread once the payment is made | ||
signedPayments.push({ | ||
...payment, | ||
type: "PT_THREAD", | ||
update: { state } | ||
}) | ||
// update new channel state | ||
newChannelState = channel | ||
// update new channel state | ||
newChannelState = channel | ||
// TODO: what happens if you have multiple thread payments | ||
// before your thread can be closed? (eg embedded payments) | ||
// PUNT on this -- AB | ||
break | ||
case 'PT_CHANNEL': | ||
const chanArgs: PaymentArgs = { | ||
recipient: 'hub', | ||
...payment.amount | ||
} | ||
newChannelState = await this.connext.signChannelState( | ||
this.validator.generateChannelPayment( | ||
curChannelState, | ||
chanArgs, | ||
) | ||
) | ||
// TODO: what happens if you have multiple thread payments | ||
// before your thread can be closed? (eg embedded payments) | ||
// PUNT on this -- AB | ||
} else { // handle channel payments | ||
const args: PaymentArgs = { | ||
recipient: 'hub', | ||
...payment.amount | ||
} | ||
newChannelState = await this.connext.signChannelState( | ||
this.validator.generateChannelPayment( | ||
curChannelState, | ||
args, | ||
signedPayments.push({ | ||
...payment, | ||
type: 'PT_CHANNEL', | ||
update: { | ||
reason: 'Payment', | ||
args: chanArgs, | ||
sigUser: newChannelState.sigUser, | ||
txCount: newChannelState.txCountGlobal, | ||
}, | ||
}) | ||
break | ||
case 'PT_LINK': | ||
// the pt link payment type has 2 cases | ||
// 1. User is the sender, in which case it should | ||
// be handled like normal channel updates | ||
// 2. User is the redeemer, in which case the response | ||
// should be handled via the 'RedeemController', | ||
// where the user posts to a separate endpoint (not buy) | ||
// check that a secret exists | ||
if (!payment.secret) { | ||
throw new Error(`Secret is not present on linked payment, aborting purchase. Purchase: ${JSON.stringify(purchase, null, 2)}`) | ||
} | ||
const linkArgs: PaymentArgs = { | ||
recipient: 'hub', | ||
...payment.amount | ||
} | ||
newChannelState = await this.connext.signChannelState( | ||
this.validator.generateChannelPayment( | ||
curChannelState, | ||
linkArgs, | ||
) | ||
) | ||
) | ||
signedPayments.push({ | ||
...payment, | ||
type: 'PT_CHANNEL', | ||
update: { | ||
reason: 'Payment', | ||
args: args, | ||
sigUser: newChannelState.sigUser, | ||
txCount: newChannelState.txCountGlobal, | ||
}, | ||
}) | ||
signedPayments.push({ | ||
...payment, | ||
type: 'PT_LINK', | ||
recipient: emptyAddress, | ||
update: { | ||
reason: 'Payment', | ||
args: linkArgs, | ||
sigUser: newChannelState.sigUser, | ||
txCount: newChannelState.txCountGlobal, | ||
}, | ||
}) | ||
break | ||
default: | ||
assertUnreachable(payment.type) | ||
} | ||
if (!newChannelState) { | ||
throw new Error(`We should never get here. Something has gone wrong with 'assertUnreachable'. Buy controller could not generate new channel state.`) | ||
} | ||
curChannelState = newChannelState | ||
@@ -104,0 +141,0 @@ } |
@@ -37,6 +37,14 @@ export const GET = 'GET' | ||
if (res.status < 200 || res.status > 299) { | ||
let text | ||
try { | ||
text = await res.text() | ||
} catch (e) { | ||
text = res.statusText | ||
} | ||
throw errorResponse( | ||
res.status, | ||
res.body, | ||
`Received non-200 response: ${res.status}`, | ||
`Received non-200 response: ${text}`, | ||
) | ||
@@ -43,0 +51,0 @@ } |
@@ -192,2 +192,26 @@ import { mkHash, getWithdrawalArgs, getExchangeArgs } from '.' | ||
async redeem(secret: string): Promise<PurchasePaymentHubResponse> { | ||
// NOTE: by default assumes this is redeemers first payment | ||
// if this is not what you are testing against, must use | ||
// the patch functions in test | ||
return { | ||
purchaseId: 'async-payment-bb', | ||
sync: { status: "CS_OPEN", | ||
updates: [{ | ||
type: 'channel', | ||
update: { | ||
reason: 'ProposePendingDeposit', | ||
createdOn: new Date(), | ||
args: getDepositArgs('full', { | ||
depositToken: [0, 1], | ||
depositWei: [0, 0], | ||
}), | ||
sigHub: mkHash('0x51512'), | ||
sigUser: '', | ||
txCount: 1, | ||
}, | ||
}]} | ||
} | ||
} | ||
async getChannel(): Promise<ChannelRow> { | ||
@@ -244,3 +268,3 @@ return { id: 0, state: getChannelState('full'), status: 'CS_OPEN' } | ||
} | ||
if (p.type == 'PT_CHANNEL') { | ||
if (p.type == 'PT_CHANNEL' || 'PT_LINK') { | ||
return { | ||
@@ -260,3 +284,7 @@ type: 'channel', | ||
type: 'thread', | ||
update: { state: p.update.state, id: p.update.state.threadId, createdOn: new Date() } | ||
update: { | ||
state: (p.update as any).state, | ||
id: (p.update as any).state.threadId, | ||
createdOn: new Date() | ||
} | ||
} as SyncResult | ||
@@ -263,0 +291,0 @@ } |
@@ -392,3 +392,2 @@ import BN = require('bn.js') | ||
| WithdrawalArgs<T> | ||
| UnsignedThreadState<T> | ||
| ConfirmPendingArgs | ||
@@ -416,3 +415,3 @@ | InvalidationArgs | ||
createdOn?: Date | ||
initialThreadStates?: UnsignedThreadState[] | ||
initialThreadStates?: ThreadState[] | ||
} | ||
@@ -727,2 +726,6 @@ | ||
/********************************* | ||
******* TYPE CONVERSIONS ******** | ||
*********************************/ | ||
export const withdrawalParamsNumericFields = [ | ||
@@ -734,7 +737,2 @@ 'withdrawalWeiUser', | ||
] | ||
/********************************* | ||
******* TYPE CONVERSIONS ******** | ||
*********************************/ | ||
export function channelUpdateToUpdateRequest(up: ChannelStateUpdate): UpdateRequest { | ||
@@ -884,2 +882,7 @@ return { | ||
export function convertWithdrawalParams<To extends NumericTypeName>(to: To, obj: WithdrawalParameters<any>): WithdrawalParameters<NumericTypes[To]> { | ||
const fromType = getType(obj.tokensToSell) | ||
return convertFields(fromType, to, withdrawalParamsNumericFields, obj) | ||
} | ||
export const proposePendingNumericArgs = [ | ||
@@ -890,3 +893,2 @@ 'depositWeiUser', | ||
'depositTokenHub', | ||
'withdrawalWeiUser', | ||
@@ -919,3 +921,3 @@ 'withdrawalWeiHub', | ||
CloseThread: convertThreadState, | ||
EmptyChannel: (to: any, args: ConfirmPendingArgs) => args, | ||
EmptyChannel: (to: any, args: EmptyChannelArgs) => args, | ||
} | ||
@@ -953,3 +955,3 @@ | ||
export type PurchasePaymentType = 'PT_CHANNEL' | 'PT_THREAD' | ||
export type PurchasePaymentType = 'PT_CHANNEL' | 'PT_THREAD' | 'PT_LINK' | ||
@@ -989,2 +991,4 @@ | ||
secret?: string | ||
// A convenience field summarizing the change in balance of the underlying | ||
@@ -1012,2 +1016,6 @@ // channel or thread. | ||
update: ThreadStateUpdate | ||
} | | ||
{ | ||
type: 'PT_LINK' | ||
update: UpdateRequest<string, PaymentArgs> // TODO: restrict to payment only? | ||
} | ||
@@ -1014,0 +1022,0 @@ )) |
@@ -193,2 +193,18 @@ import { subOrZero, objMap } from './StateGenerator' | ||
// ensure the deposit is correctly signed by user if the sig user | ||
// exists | ||
if (args.sigUser) { | ||
try { | ||
const argsStr = convertDeposit("str", args) | ||
const proposal: SignedDepositRequestProposal = { | ||
amountToken: argsStr.depositTokenUser, | ||
amountWei: argsStr.depositWeiUser, | ||
sigUser: args.sigUser, | ||
} | ||
this.assertDepositRequestSigner(proposal, prev.user) | ||
} catch (e) { | ||
return `Invalid signer detected. ` + e.message + ` (prev: ${this.logChannel(prev)}, args: ${this.logArgs(args, "ProposePendingDeposit")}` | ||
} | ||
} | ||
return null | ||
@@ -343,2 +359,12 @@ } | ||
public async generateConfirmPending(prevStr: ChannelState, args: ConfirmPendingArgs): Promise<UnsignedChannelState> { | ||
const prev = convertChannelState("bn", prevStr) | ||
const error = await this.confirmPending(prev, args) | ||
if (error) { | ||
throw new Error(error) | ||
} | ||
return this.stateGenerator.confirmPending(prev) | ||
} | ||
public async emptyChannel(prev: ChannelStateBN, args: EmptyChannelArgs): Promise<string | null> { | ||
@@ -421,12 +447,2 @@ // apply .toLowerCase to all strings on the prev object | ||
public async generateConfirmPending(prevStr: ChannelState, args: ConfirmPendingArgs): Promise<UnsignedChannelState> { | ||
const prev = convertChannelState("bn", prevStr) | ||
const error = await this.confirmPending(prev, args) | ||
if (error) { | ||
throw new Error(error) | ||
} | ||
return this.stateGenerator.confirmPending(prev) | ||
} | ||
// NOTE: the prev here is NOT the previous state in the state-chain | ||
@@ -633,5 +649,5 @@ // of events. Instead it is the previously "valid" update, meaning the | ||
private cantAffordFromBalance(state: ChannelStateBN, value: Partial<PaymentBN>, payor: "hub" | "user", currency?: "token" | "wei"): string | null | ||
private cantAffordFromBalance(state: ThreadStateBN, value: Partial<PaymentBN>, payor: "sender", currency?: "token" | "wei"): string | null | ||
private cantAffordFromBalance(state: ChannelStateBN | ThreadStateBN, value: Partial<PaymentBN>, payor: "hub" | "user" | "sender", currency?: "token" | "wei"): string | null { | ||
public cantAffordFromBalance(state: ChannelStateBN, value: Partial<PaymentBN>, payor: "hub" | "user", currency?: "token" | "wei"): string | null | ||
public cantAffordFromBalance(state: ThreadStateBN, value: Partial<PaymentBN>, payor: "sender", currency?: "token" | "wei"): string | null | ||
public cantAffordFromBalance(state: ChannelStateBN | ThreadStateBN, value: Partial<PaymentBN>, payor: "hub" | "user" | "sender", currency?: "token" | "wei"): string | null { | ||
const prefix = "balance" | ||
@@ -638,0 +654,0 @@ const currencies = currency ? [currency] : ["token", "wei"] |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
4409005
629
26957