Socket
Socket
Sign inDemoInstall

@connext/cf-core

Package Overview
Dependencies
Maintainers
4
Versions
198
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@connext/cf-core - npm Package Compare versions

Comparing version 1.2.12 to 1.2.13

1

dist/src/methods/errors.d.ts
import { BigNumber } from "ethers/utils";
export declare const APP_ALREADY_UNINSTALLED: (id: string) => string;
export declare const CANNOT_DEPOSIT = "Cannot deposit while another deposit is occurring in the channel.";
export declare const COIN_BALANCE_NOT_PROPOSED = "No coin balance refund app proposed in channel.";
export declare const BALANCE_REFUND_APP_ALREADY_INSTALLED = "Balance refund app is installed, please uninstall first.";

@@ -5,0 +6,0 @@ export declare const BALANCE_REFUND_APP_NOT_INSTALLED = "Balance refund app is not installed.";

@@ -7,2 +7,3 @@ "use strict";

exports.CANNOT_DEPOSIT = "Cannot deposit while another deposit is occurring in the channel.";
exports.COIN_BALANCE_NOT_PROPOSED = "No coin balance refund app proposed in channel.";
exports.BALANCE_REFUND_APP_ALREADY_INSTALLED = "Balance refund app is installed, please uninstall first.";

@@ -9,0 +10,0 @@ exports.BALANCE_REFUND_APP_NOT_INSTALLED = "Balance refund app is not installed.";

7

dist/src/methods/state-channel/deposit/controller.js

@@ -34,5 +34,8 @@ "use strict";

const channel = await store.getStateChannel(multisigAddress);
if (channel.hasAppInstanceOfKind(networkContext.CoinBalanceRefundApp)) {
if (channel.hasBalanceRefundAppInstance(networkContext.CoinBalanceRefundApp, tokenAddress)) {
throw Error(errors_1.CANNOT_DEPOSIT);
}
if (!channel.hasProposedBalanceRefundAppInstance(networkContext.CoinBalanceRefundApp, tokenAddress)) {
throw Error(errors_1.COIN_BALANCE_NOT_PROPOSED);
}
const address = await requestHandler.getSignerAddress();

@@ -80,3 +83,3 @@ if (tokenAddress !== constants_1.CONVENTION_FOR_ETH_TOKEN_ADDRESS) {

multisigBalance,
tokenAddress: params.tokenAddress,
tokenAddress: params.tokenAddress
};

@@ -83,0 +86,0 @@ }

@@ -23,3 +23,3 @@ "use strict";

const depositContext = await getDepositContext(params, publicIdentifier, provider, networkContext, tokenAddress);
const InstallProtocolParams = {
const installProtocolParams = {
initialState: depositContext.initialState,

@@ -40,3 +40,3 @@ initiatorXpub: publicIdentifier,

};
await protocolRunner.initiateProtocol(machine_1.Protocol.Install, stateChannelsMap, InstallProtocolParams);
await protocolRunner.initiateProtocol(machine_1.Protocol.Install, stateChannelsMap, installProtocolParams);
}

@@ -73,3 +73,3 @@ exports.installBalanceRefundApp = installBalanceRefundApp;

type: types_1.NODE_EVENTS.DEPOSIT_FAILED,
data: { errors, params },
data: { errors, params }
};

@@ -93,3 +93,3 @@ if (e.toString().includes("reject") || e.toString().includes("denied")) {

txHash: txResponse.hash
},
}
});

@@ -101,8 +101,16 @@ await txResponse.wait(blocksNeededForConfirmation);

const { publicIdentifier, store, protocolRunner, networkContext } = requestHandler;
const { multisigAddress } = params;
const { multisigAddress, tokenAddress } = params;
const { CoinBalanceRefundApp } = networkContext;
const [peerAddress] = await models_1.StateChannel.getPeersAddressFromChannel(publicIdentifier, store, multisigAddress);
const stateChannel = await store.getStateChannel(params.multisigAddress);
const refundApp = stateChannel.getAppInstanceOfKind(CoinBalanceRefundApp);
const stateChannelsMap = await protocolRunner.initiateProtocol(machine_1.Protocol.Uninstall, new Map([
let refundApp;
try {
refundApp = stateChannel.getBalanceRefundAppInstance(CoinBalanceRefundApp, tokenAddress);
}
catch (e) {
if (e.message.includes(`No CoinBalanceRefund app instance`)) {
return;
}
}
await protocolRunner.initiateProtocol(machine_1.Protocol.Uninstall, new Map([
[stateChannel.multisigAddress, stateChannel]

@@ -109,0 +117,0 @@ ]), {

@@ -47,4 +47,4 @@ "use strict";

}
if (channel.hasAppInstanceOfKind(networkContext.CoinBalanceRefundApp)) {
const balanceRefundApp = channel.getAppInstanceOfKind(networkContext.CoinBalanceRefundApp);
if (channel.hasBalanceRefundAppInstance(networkContext.CoinBalanceRefundApp, params.tokenAddress)) {
const balanceRefundApp = channel.getBalanceRefundAppInstance(networkContext.CoinBalanceRefundApp, params.tokenAddress);
const appIsCorrectlyInstalled = balanceRefundApp.latestState["recipient"] === freeBalanceAddress &&

@@ -54,4 +54,7 @@ multisigBalance.eq(balanceRefundApp.latestState["threshold"]);

return {
multisigBalance,
recipient: freeBalanceAddress
freeBalance: channel
.getFreeBalanceClass()
.withTokenAddress(params.tokenAddress),
recipient: freeBalanceAddress,
tokenAddress: params.tokenAddress
};

@@ -63,4 +66,7 @@ }

return {
multisigBalance,
recipient: freeBalanceAddress
freeBalance: channel
.getFreeBalanceClass()
.withTokenAddress(params.tokenAddress),
recipient: freeBalanceAddress,
tokenAddress: params.tokenAddress
};

@@ -67,0 +73,0 @@ }

@@ -48,9 +48,9 @@ "use strict";

multisigBalance,
tokenAddress,
tokenAddress
};
}
await operation_1.uninstallBalanceRefundApp(requestHandler, Object.assign({}, params, { tokenAddress: constants_2.CONVENTION_FOR_ETH_TOKEN_ADDRESS, amount: constants_1.Zero }), await provider.getBlockNumber());
await operation_1.uninstallBalanceRefundApp(requestHandler, Object.assign({}, params, { tokenAddress, amount: constants_1.Zero }), await provider.getBlockNumber());
return {
multisigBalance,
tokenAddress,
tokenAddress
};

@@ -57,0 +57,0 @@ }

@@ -29,6 +29,6 @@ "use strict";

const stateChannel = await store.getStateChannel(params.multisigAddress);
if (stateChannel.hasAppInstanceOfKind(networkContext.CoinBalanceRefundApp)) {
const tokenAddress = params.tokenAddress || constants_1.CONVENTION_FOR_ETH_TOKEN_ADDRESS;
if (stateChannel.hasBalanceRefundAppInstance(networkContext.CoinBalanceRefundApp, tokenAddress)) {
throw Error(errors_1.CANNOT_WITHDRAW);
}
const tokenAddress = params.tokenAddress || constants_1.CONVENTION_FOR_ETH_TOKEN_ADDRESS;
const senderBalance = stateChannel

@@ -35,0 +35,0 @@ .getFreeBalanceClass()

@@ -29,2 +29,6 @@ import { BigNumber } from "ethers/utils";

getAppInstanceOfKind(address: string): AppInstance;
getAppInstancesOfKind(address: string): AppInstance[];
hasBalanceRefundAppInstance(balanceRefundAppDefinitionAddress: string, tokenAddress: string): boolean;
hasProposedBalanceRefundAppInstance(balanceRefundAppDefinitionAddress: string, tokenAddress: string): boolean;
getBalanceRefundAppInstance(balanceRefundAppDefinitionAddress: string, tokenAddress?: string): AppInstance;
isAppInstanceInstalled(appInstanceIdentityHash: string): boolean;

@@ -31,0 +35,0 @@ getSigningKeysFor(addressIndex: number): string[];

@@ -8,4 +8,5 @@ "use strict";

const free_balance_1 = require("./free-balance");
const constants_1 = require("../constants");
exports.HARD_CODED_ASSUMPTIONS = {
freeBalanceDefaultTimeout: 172800,
freeBalanceDefaultTimeout: 172800
};

@@ -78,4 +79,31 @@ const ERRORS = {

if (appInstances.length !== 1) {
throw Error(`Either 0 or more than 1 AppInstance of addr ${address} exists on channel: ${this.multisigAddress}`);
}
return appInstances[0];
}
getAppInstancesOfKind(address) {
const appInstances = Array.from(this.appInstances.values()).filter((appInstance) => {
return appInstance.appInterface.addr === address;
});
if (appInstances.length === 0) {
throw Error(`No AppInstance of addr ${address} exists on channel: ${this.multisigAddress}`);
}
return appInstances;
}
hasBalanceRefundAppInstance(balanceRefundAppDefinitionAddress, tokenAddress) {
return (Array.from(this.appInstances.values()).filter((appInstance) => appInstance.appInterface.addr === balanceRefundAppDefinitionAddress &&
appInstance.latestState["tokenAddress"] === tokenAddress).length > 0);
}
hasProposedBalanceRefundAppInstance(balanceRefundAppDefinitionAddress, tokenAddress) {
return (Array.from(this.proposedAppInstances.values()).filter((appInstance) => appInstance.appDefinition === balanceRefundAppDefinitionAddress &&
appInstance.initialState["tokenAddress"] === tokenAddress).length > 0);
}
getBalanceRefundAppInstance(balanceRefundAppDefinitionAddress, tokenAddress = constants_1.CONVENTION_FOR_ETH_TOKEN_ADDRESS) {
const appInstances = this.getAppInstancesOfKind(balanceRefundAppDefinitionAddress).filter((appInstance) => appInstance.latestState["tokenAddress"] === tokenAddress);
if (appInstances.length === 0) {
throw Error(`No CoinBalanceRefund app instance of tokenAddress ${tokenAddress} exists on channel: ${this.multisigAddress}`);
}
if (appInstances.length > 1) {
throw Error(`More than 1 CoinBalanceRefund app instance of tokenAddress ${tokenAddress} exists on channel: ${this.multisigAddress}`);
}
return appInstances[0];

@@ -82,0 +110,0 @@ }

@@ -21,12 +21,12 @@ "use strict";

to: sender.freeBalanceAddress,
amount: action.amount,
amount: action.amount
},
{
to: intermediary.freeBalanceAddress,
amount: constants_1.Zero,
},
amount: constants_1.Zero
}
];
linkStatesSender.push({
action,
state: Object.assign({}, state, { transfers: hubTransfers }),
state: Object.assign({}, state, { transfers: hubTransfers })
});

@@ -36,3 +36,3 @@ }

linkStatesRedeemer,
linkStatesSender,
linkStatesSender
};

@@ -68,4 +68,4 @@ }

multisigAddressBC = await utils_2.createChannel(nodeB, nodeC);
await utils_2.collateralizeChannel(multisigAddressAB, nodeA, undefined, utils_1.bigNumberify(15));
await utils_2.collateralizeChannel(multisigAddressBC, nodeB, undefined, utils_1.bigNumberify(15));
await utils_2.deposit(nodeA, multisigAddressAB, utils_1.bigNumberify(15), nodeB);
await utils_2.deposit(nodeB, multisigAddressBC, utils_1.bigNumberify(15), nodeC);
});

@@ -72,0 +72,0 @@ it("should be able to redeem a pregenerated linked payment while simultaneously receiving a direct transfer", async (done) => {

@@ -16,3 +16,3 @@ "use strict";

loglevel_1.default.setLevel(loglevel_1.default.levels.SILENT);
describe("Node method follows spec - deploy state desposit holder", () => {
describe("Node method follows spec - deploy state deposit holder", () => {
let nodeA;

@@ -37,3 +37,3 @@ let nodeB;

const startingMultisigBalance = await provider.getBalance(multisigAddress);
await utils_2.deposit(nodeA, multisigAddress, constants_1.One);
await utils_2.deposit(nodeA, multisigAddress, constants_1.One, nodeB);
const postDepositMultisigBalance = await provider.getBalance(multisigAddress);

@@ -40,0 +40,0 @@ expect(postDepositMultisigBalance).toBeEq(startingMultisigBalance.add(constants_1.One));

@@ -19,3 +19,3 @@ "use strict";

"Virtual AppInstance with Node C. Node C rejects proposal. Node A confirms rejection", () => {
it("sends proposal with non-null initial state", async (done) => {
it.skip("sends proposal with non-null initial state", async (done) => {
await utils_1.createChannel(nodeA, nodeB);

@@ -22,0 +22,0 @@ await utils_1.createChannel(nodeB, nodeC);

@@ -13,3 +13,2 @@ "use strict";

const constants_2 = require("../../src/constants");
const errors_1 = require("../../src/methods/errors");
const bignumber_jest_matcher_1 = require("../machine/integration/bignumber-jest-matcher");

@@ -25,3 +24,3 @@ const setup_1 = require("./setup");

data: {
value: params.amount,
value: params.amount
}

@@ -32,3 +31,3 @@ };

type: src_1.NODE_EVENTS.DEPOSIT_CONFIRMED,
data: params,
data: params
};

@@ -61,28 +60,17 @@ initiator.once(src_1.NODE_EVENTS.DEPOSIT_STARTED, (msg) => {

it("has the right balance before an ERC20 deposit has been made", async () => {
const erc20ContractAddress = global["networkContext"]
.DolphinCoin;
const erc20ContractAddress = global["networkContext"].DolphinCoin;
const freeBalanceState = await utils_1.getFreeBalanceState(nodeA, multisigAddress, erc20ContractAddress);
expect(Object.values(freeBalanceState)).toMatchObject([constants_1.Zero, constants_1.Zero]);
});
it("has the right balance for both parties after deposits", async (done) => {
const depositReq = utils_1.constructDepositRpc(multisigAddress, constants_1.One);
it("has the right balance for both parties after deposits", async () => {
const preDepositBalance = await provider.getBalance(multisigAddress);
nodeB.once(src_1.NODE_EVENTS.DEPOSIT_CONFIRMED, async (msg) => {
confirmDepositMessages(nodeB, nodeA, depositReq.parameters);
await nodeB.rpcRouter.dispatch(depositReq);
expect(await provider.getBalance(multisigAddress)).toBeEq(preDepositBalance.add(2));
const freeBalanceState = await utils_1.getFreeBalanceState(nodeA, multisigAddress);
expect(Object.values(freeBalanceState)).toMatchObject([constants_1.One, constants_1.One]);
done();
});
nodeA.off(src_1.NODE_EVENTS.DEPOSIT_CONFIRMED);
confirmDepositMessages(nodeA, nodeB, depositReq.parameters);
await nodeA.rpcRouter.dispatch(depositReq);
await utils_1.deposit(nodeB, multisigAddress, constants_1.One, nodeA);
await utils_1.deposit(nodeA, multisigAddress, constants_1.One, nodeB);
expect(await provider.getBalance(multisigAddress)).toBeEq(preDepositBalance.add(2));
const freeBalanceState = await utils_1.getFreeBalanceState(nodeA, multisigAddress);
expect(Object.values(freeBalanceState)).toMatchObject([constants_1.One, constants_1.One]);
});
it("updates balances correctly when depositing both ERC20 tokens and ETH", async () => {
const erc20ContractAddress = global["networkContext"]
.DolphinCoin;
const erc20ContractAddress = global["networkContext"].DolphinCoin;
const erc20Contract = new ethers_1.Contract(erc20ContractAddress, DolphinCoin_json_1.default.abi, new providers_1.JsonRpcProvider(global["ganacheURL"]));
const erc20DepositRequest = utils_1.constructDepositRpc(multisigAddress, constants_1.One, erc20ContractAddress);
await expect(nodeA.rpcRouter.dispatch(erc20DepositRequest)).rejects.toThrowError(errors_1.INSUFFICIENT_ERC20_FUNDS_TO_DEPOSIT(await nodeA.signerAddress(), erc20ContractAddress, constants_1.One, constants_1.Zero));
await utils_1.transferERC20Tokens(await nodeA.signerAddress());

@@ -92,4 +80,4 @@ await utils_1.transferERC20Tokens(await nodeB.signerAddress());

const preDepositERC20Balance = await erc20Contract.functions.balanceOf(multisigAddress);
await nodeA.rpcRouter.dispatch(erc20DepositRequest);
await nodeB.rpcRouter.dispatch(erc20DepositRequest);
await utils_1.deposit(nodeA, multisigAddress, constants_1.One, nodeB, erc20ContractAddress);
await utils_1.deposit(nodeB, multisigAddress, constants_1.One, nodeA, erc20ContractAddress);
expect(await provider.getBalance(multisigAddress)).toEqual(preDepositBalance);

@@ -99,6 +87,5 @@ expect(await erc20Contract.functions.balanceOf(multisigAddress)).toEqual(preDepositERC20Balance.add(constants_1.Two));

await confirmEthAndERC20FreeBalances(nodeB, multisigAddress, erc20ContractAddress);
const ethDepositReq = utils_1.constructDepositRpc(multisigAddress, constants_1.One);
preDepositBalance = await provider.getBalance(multisigAddress);
await nodeA.rpcRouter.dispatch(ethDepositReq);
await nodeB.rpcRouter.dispatch(ethDepositReq);
await utils_1.deposit(nodeA, multisigAddress, constants_1.One, nodeB);
await utils_1.deposit(nodeB, multisigAddress, constants_1.One, nodeA);
expect(await provider.getBalance(multisigAddress)).toBeEq(preDepositBalance.add(2));

@@ -111,8 +98,5 @@ const freeBalanceState = await utils_1.getFreeBalanceState(nodeA, multisigAddress);

const tokenIndexedFreeBalances = await utils_1.getTokenIndexedFreeBalanceStates(node, multisigAddress);
expect(Object.values(tokenIndexedFreeBalances[constants_2.CONVENTION_FOR_ETH_TOKEN_ADDRESS])).toMatchObject([
constants_1.Zero,
constants_1.Zero,
]);
expect(Object.values(tokenIndexedFreeBalances[constants_2.CONVENTION_FOR_ETH_TOKEN_ADDRESS])).toMatchObject([constants_1.Zero, constants_1.Zero]);
expect(Object.values(tokenIndexedFreeBalances[erc20ContractAddress])).toMatchObject([constants_1.One, constants_1.One]);
}
//# sourceMappingURL=secure-deposit.spec.js.map

@@ -26,3 +26,3 @@ "use strict";

from: initiator.freeBalanceAddress,
to: params.multisigAddress,
to: params.multisigAddress
}

@@ -42,3 +42,3 @@ }

"data.txReceipt.transactionHash",
"data.txReceipt.transactionIndex",
"data.txReceipt.transactionIndex"
]);

@@ -52,3 +52,3 @@ });

initiator.once(src_1.NODE_EVENTS.WITHDRAWAL_STARTED, (msg) => {
utils_2.assertNodeMessage(msg, startedMsg, ['data.txHash']);
utils_2.assertNodeMessage(msg, startedMsg, ["data.txHash"]);
});

@@ -77,3 +77,3 @@ responder.once(src_1.NODE_EVENTS.WITHDRAWAL_STARTED, (msg) => {

const startingMultisigBalance = await provider.getBalance(multisigAddress);
await utils_2.deposit(nodeA, multisigAddress, constants_1.One);
await utils_2.deposit(nodeA, multisigAddress, constants_1.One, nodeB);
const postDepositMultisigBalance = await provider.getBalance(multisigAddress);

@@ -98,3 +98,3 @@ expect(postDepositMultisigBalance).toBeEq(startingMultisigBalance.add(constants_1.One));

const startingMultisigTokenBalance = await erc20Contract.functions.balanceOf(multisigAddress);
await utils_2.deposit(nodeA, multisigAddress, constants_1.One, erc20ContractAddress);
await utils_2.deposit(nodeA, multisigAddress, constants_1.One, nodeB, erc20ContractAddress);
const postDepositMultisigTokenBalance = await erc20Contract.functions.balanceOf(multisigAddress);

@@ -112,3 +112,3 @@ expect(postDepositMultisigTokenBalance).toBeEq(startingMultisigTokenBalance.add(constants_1.One));

const startingMultisigBalance = await provider.getBalance(multisigAddress);
await utils_2.deposit(nodeA, multisigAddress, constants_1.One);
await utils_2.deposit(nodeA, multisigAddress, constants_1.One, nodeB);
const postDepositMultisigBalance = await provider.getBalance(multisigAddress);

@@ -115,0 +115,0 @@ const getFreeBalance = async (node) => {

@@ -11,2 +11,3 @@ "use strict";

expect.extend({ toBeLt: bignumber_jest_matcher_1.toBeLt, toBeEq: bignumber_jest_matcher_1.toBeEq });
const { CoinBalanceRefundApp } = global["networkContext"];
describe("Node method follows spec - install balance refund", () => {

@@ -44,9 +45,3 @@ let multisigAddress;

expect(multisigBalance).toBeEq(preDepositMultisig.add(constants_1.One));
await nodeA.rpcRouter.dispatch({
id: Date.now(),
methodName: types_1.Node.RpcMethodName.RESCIND_DEPOSIT_RIGHTS,
parameters: {
multisigAddress
}
});
await utils_1.rescindDepositRights(nodeA, multisigAddress);
const [postSendBalA, postSendBalB] = await utils_1.getBalances(nodeA, nodeB, multisigAddress, constants_1.AddressZero);

@@ -57,10 +52,3 @@ expect(postSendBalA).toBeEq(1);

});
await nodeA.rpcRouter.dispatch({
id: Date.now(),
methodName: types_1.Node.RpcMethodName.REQUEST_DEPOSIT_RIGHTS,
parameters: {
multisigAddress,
tokenAddress: constants_1.AddressZero
}
});
await utils_1.requestDepositRights(nodeA, multisigAddress);
});

@@ -81,9 +69,3 @@ it("install app with tokens, sending tokens should increase free balance", async (done) => {

await utils_1.transferERC20Tokens(multisigAddress, erc20TokenAddress);
await nodeB.rpcRouter.dispatch({
id: Date.now(),
methodName: types_1.Node.RpcMethodName.RESCIND_DEPOSIT_RIGHTS,
parameters: {
multisigAddress
}
});
await utils_1.rescindDepositRights(nodeB, multisigAddress, erc20TokenAddress);
const [postSendBalA, postSendBalB] = await utils_1.getBalances(nodeA, nodeB, multisigAddress, erc20TokenAddress);

@@ -94,10 +76,64 @@ expect(postSendBalA).toBeEq(1);

});
await nodeA.rpcRouter.dispatch({
id: Date.now(),
methodName: types_1.Node.RpcMethodName.REQUEST_DEPOSIT_RIGHTS,
parameters: {
multisigAddress,
tokenAddress: erc20TokenAddress
await utils_1.requestDepositRights(nodeA, multisigAddress, erc20TokenAddress);
});
it("install app with both eth and tokens, sending eth and tokens should increase free balance", async (done) => {
const erc20TokenAddress = global["networkContext"].DolphinCoin;
let installedCount = 0;
nodeB.on(types_1.NODE_EVENTS.INSTALL, async () => {
installedCount += 1;
const [appInstanceNodeA] = await utils_1.getInstalledAppInstances(nodeA);
const [appInstanceNodeB] = await utils_1.getInstalledAppInstances(nodeB);
expect(appInstanceNodeA).toBeDefined();
expect(appInstanceNodeA).toEqual(appInstanceNodeB);
expect(appInstanceNodeA.latestState.recipient).toBe(machine_1.xkeyKthAddress(nodeA.publicIdentifier, 0));
const proposedAppsA = await utils_1.getProposedAppInstances(nodeA);
expect(proposedAppsA.length).toBe(0);
if (installedCount < 2) {
return;
}
const [preSendBalAToken, preSendBalBToken] = await utils_1.getBalances(nodeA, nodeB, multisigAddress, erc20TokenAddress);
expect(preSendBalAToken).toBeEq(0);
expect(preSendBalBToken).toBeEq(0);
await utils_1.transferERC20Tokens(multisigAddress, erc20TokenAddress);
await utils_1.rescindDepositRights(nodeB, multisigAddress, erc20TokenAddress);
const [postSendBalAToken, postSendBalBToken] = await utils_1.getBalances(nodeA, nodeB, multisigAddress, erc20TokenAddress);
expect(postSendBalAToken).toBeEq(1);
expect(postSendBalBToken).toBeEq(0);
const [preSendBalAEth, preSendBalBEth] = await utils_1.getBalances(nodeA, nodeB, multisigAddress, constants_1.AddressZero);
expect(preSendBalAEth).toBeEq(0);
expect(preSendBalBEth).toBeEq(0);
const preDepositMultisig = await provider.getBalance(multisigAddress);
const tx = await provider.getSigner().sendTransaction({
to: multisigAddress,
value: constants_1.One
});
await provider.waitForTransaction(tx.hash);
const multisigBalance = await provider.getBalance(multisigAddress);
expect(multisigBalance).toBeEq(preDepositMultisig.add(constants_1.One));
await utils_1.rescindDepositRights(nodeB, multisigAddress);
const [postSendBalAEth, postSendBalBEth] = await utils_1.getBalances(nodeA, nodeB, multisigAddress, constants_1.AddressZero);
expect(postSendBalAEth).toBeEq(1);
expect(postSendBalBEth).toBeEq(0);
done();
});
let parameters = await utils_1.getProposeCoinBalanceRefundAppParams(multisigAddress, nodeA.publicIdentifier, nodeB.publicIdentifier, constants_1.AddressZero);
await new Promise(async (res) => {
nodeB.once(types_1.NODE_EVENTS.PROPOSE_INSTALL, data => res(data));
await nodeA.rpcRouter.dispatch({
id: Date.now(),
methodName: types_1.Node.RpcMethodName.PROPOSE_INSTALL,
parameters
});
});
await utils_1.requestDepositRights(nodeA, multisigAddress);
parameters = await utils_1.getProposeCoinBalanceRefundAppParams(multisigAddress, nodeA.publicIdentifier, nodeB.publicIdentifier, erc20TokenAddress);
await new Promise(async (res) => {
nodeB.once(types_1.NODE_EVENTS.PROPOSE_INSTALL, data => res(data));
await nodeA.rpcRouter.dispatch({
id: Date.now(),
methodName: types_1.Node.RpcMethodName.PROPOSE_INSTALL,
parameters
});
});
await utils_1.requestDepositRights(nodeA, multisigAddress, erc20TokenAddress);
});

@@ -113,20 +149,7 @@ it("install does not error if already installed", async (done) => {

});
await nodeA.rpcRouter.dispatch({
id: Date.now(),
methodName: types_1.Node.RpcMethodName.REQUEST_DEPOSIT_RIGHTS,
parameters: {
multisigAddress,
tokenAddress: constants_1.AddressZero
}
});
await utils_1.requestDepositRights(nodeA, multisigAddress);
});
it("can uninstall with no changes", async (done) => {
nodeB.on(types_1.NODE_EVENTS.INSTALL, async () => {
await nodeB.rpcRouter.dispatch({
id: Date.now(),
methodName: types_1.Node.RpcMethodName.RESCIND_DEPOSIT_RIGHTS,
parameters: {
multisigAddress
}
});
await utils_1.rescindDepositRights(nodeB, multisigAddress);
const appInstancesNodeA = await utils_1.getInstalledAppInstances(nodeA);

@@ -138,19 +161,6 @@ const appInstancesNodeB = await utils_1.getInstalledAppInstances(nodeB);

});
await nodeA.rpcRouter.dispatch({
id: Date.now(),
methodName: types_1.Node.RpcMethodName.REQUEST_DEPOSIT_RIGHTS,
parameters: {
multisigAddress,
tokenAddress: constants_1.AddressZero
}
});
await utils_1.requestDepositRights(nodeA, multisigAddress);
});
it("uninstall does not error if not installed", async () => {
await nodeA.rpcRouter.dispatch({
id: Date.now(),
methodName: types_1.Node.RpcMethodName.RESCIND_DEPOSIT_RIGHTS,
parameters: {
multisigAddress
}
});
await utils_1.rescindDepositRights(nodeA, multisigAddress);
const appInstancesNodeA = await utils_1.getInstalledAppInstances(nodeA);

@@ -157,0 +167,0 @@ const appInstancesNodeB = await utils_1.getInstalledAppInstances(nodeB);

@@ -12,2 +12,20 @@ import { AppABIEncodings, AppInstanceJson, AppInstanceProposal, ContractABI, Node as NodeTypes, OutcomeType, SolidityValueType } from "@connext/cf-types";

}
export declare function requestDepositRights(node: Node, multisigAddress: string, tokenAddress?: string): Promise<JsonRpcResponse>;
export declare function constructRequestDepositRightsRpcCall(multisigAddress: string, tokenAddress?: string): {
id: number;
methodName: NodeTypes.RpcMethodName;
parameters: {
multisigAddress: string;
tokenAddress: string;
};
};
export declare function rescindDepositRights(node: Node, multisigAddress: string, tokenAddress?: string): Promise<JsonRpcResponse>;
export declare function constructRescindDepositRightsRpcCall(multisigAddress: string, tokenAddress?: string): {
id: number;
methodName: NodeTypes.RpcMethodName;
parameters: {
multisigAddress: string;
tokenAddress: string;
};
};
export declare function assertNodeMessage(msg: EventEmittedMessage, expected: any, shouldExist?: string[]): void;

@@ -17,3 +35,9 @@ export declare function assertProposeMessage(senderId: string, msg: ProposeMessage, params: ProposeInstallProtocolParams): void;

export declare function getMultisigCreationAddress(node: Node, xpubs: string[]): Promise<string>;
export declare function constructChannelCreationRpc(owners: string[]): Rpc;
export declare function constructChannelCreationRpc(owners: string[]): {
id: number;
methodName: NodeTypes.RpcMethodName;
parameters: {
owners: string[];
};
};
export declare function getChannelAddresses(node: Node): Promise<Set<string>>;

@@ -26,3 +50,4 @@ export declare function getAppInstance(node: Node, appInstanceId: string): Promise<AppInstanceJson>;

export declare function getProposedAppInstances(node: Node): Promise<AppInstanceProposal[]>;
export declare function deposit(node: Node, multisigAddress: string, amount?: BigNumber, tokenAddress?: string): Promise<unknown>;
export declare function getProposeCoinBalanceRefundAppParams(multisigAddress: string, balanceRefundRecipientIdentifer: string, proposedToIdentifier: string, tokenAddress?: string): Promise<NodeTypes.ProposeInstallParams>;
export declare function deposit(node: Node, multisigAddress: string, amount: BigNumber | undefined, proposedToNode: Node, tokenAddress?: string): Promise<unknown>;
export declare function deployStateDepositHolder(node: Node, multisigAddress: string): Promise<string>;

@@ -43,3 +68,3 @@ export declare function constructDepositRpc(multisigAddress: string, amount: BigNumber, tokenAddress?: string): Rpc;

export declare function constructUninstallVirtualRpc(appInstanceId: string, intermediaryIdentifier: string): Rpc;
export declare function collateralizeChannel(multisigAddress: string, node1: Node, node2?: Node, amount?: BigNumber, tokenAddress?: string): Promise<void>;
export declare function collateralizeChannel(multisigAddress: string, node1: Node, node2: Node, amount?: BigNumber, tokenAddress?: string): Promise<void>;
export declare function createChannel(nodeA: Node, nodeB: Node): Promise<string>;

@@ -46,0 +71,0 @@ export declare function installApp(nodeA: Node, nodeB: Node, appDefinition: string, initialState?: SolidityValueType, initiatorDeposit?: BigNumber, initiatorDepositTokenAddress?: string, responderDeposit?: BigNumber, responderDepositTokenAddress?: string): Promise<[string, ProposeInstallProtocolParams]>;

@@ -31,3 +31,33 @@ "use strict";

const utils_2 = require("../../src/utils");
const { TicTacToeApp, SimpleTransferApp, UnidirectionalLinkedTransferApp, UnidirectionalTransferApp } = global["networkContext"];
const { CoinBalanceRefundApp, TicTacToeApp, SimpleTransferApp, UnidirectionalLinkedTransferApp, UnidirectionalTransferApp } = global["networkContext"];
async function requestDepositRights(node, multisigAddress, tokenAddress = constants_1.AddressZero) {
return await node.rpcRouter.dispatch(constructRequestDepositRightsRpcCall(multisigAddress, tokenAddress));
}
exports.requestDepositRights = requestDepositRights;
function constructRequestDepositRightsRpcCall(multisigAddress, tokenAddress = constants_1.AddressZero) {
return {
id: Date.now(),
methodName: cf_types_1.Node.RpcMethodName.REQUEST_DEPOSIT_RIGHTS,
parameters: {
multisigAddress,
tokenAddress
}
};
}
exports.constructRequestDepositRightsRpcCall = constructRequestDepositRightsRpcCall;
async function rescindDepositRights(node, multisigAddress, tokenAddress = constants_1.AddressZero) {
return await node.rpcRouter.dispatch(constructRescindDepositRightsRpcCall(multisigAddress, tokenAddress));
}
exports.rescindDepositRights = rescindDepositRights;
function constructRescindDepositRightsRpcCall(multisigAddress, tokenAddress = constants_1.AddressZero) {
return {
id: Date.now(),
methodName: cf_types_1.Node.RpcMethodName.RESCIND_DEPOSIT_RIGHTS,
parameters: {
multisigAddress,
tokenAddress
}
};
}
exports.constructRescindDepositRightsRpcCall = constructRescindDepositRightsRpcCall;
function assertNodeMessage(msg, expected, shouldExist = []) {

@@ -50,5 +80,5 @@ shouldExist.forEach(key => {

data: {
params: Object.assign({}, emittedParams, { proposedToIdentifier }),
params: Object.assign({}, emittedParams, { proposedToIdentifier })
}
}, ['data.appInstanceId']);
}, ["data.appInstanceId"]);
}

@@ -74,10 +104,9 @@ exports.assertProposeMessage = assertProposeMessage;

function constructChannelCreationRpc(owners) {
return src_1.jsonRpcDeserialize({
return {
id: Date.now(),
method: cf_types_1.Node.RpcMethodName.CREATE_CHANNEL,
jsonrpc: "2.0",
params: {
owners,
methodName: cf_types_1.Node.RpcMethodName.CREATE_CHANNEL,
parameters: {
owners
}
});
};
}

@@ -140,8 +169,7 @@ exports.constructChannelCreationRpc = constructChannelCreationRpc;

async function getInstalledAppInstances(node) {
const rpc = src_1.jsonRpcDeserialize({
jsonrpc: "2.0",
const rpc = {
id: Date.now(),
method: cf_types_1.Node.RpcMethodName.GET_APP_INSTANCES,
params: {}
});
methodName: cf_types_1.Node.RpcMethodName.GET_APP_INSTANCES,
parameters: {}
};
const response = (await node.rpcRouter.dispatch(rpc));

@@ -153,8 +181,7 @@ const result = response.result.result;

async function getProposedAppInstances(node) {
const rpc = src_1.jsonRpcDeserialize({
jsonrpc: "2.0",
const rpc = {
id: Date.now(),
method: cf_types_1.Node.RpcMethodName.GET_PROPOSED_APP_INSTANCES,
params: {}
});
methodName: cf_types_1.Node.RpcMethodName.GET_PROPOSED_APP_INSTANCES,
parameters: {}
};
const response = (await node.rpcRouter.dispatch(rpc));

@@ -166,3 +193,46 @@ const result = response.result

exports.getProposedAppInstances = getProposedAppInstances;
async function deposit(node, multisigAddress, amount = constants_1.One, tokenAddress) {
async function getProposeCoinBalanceRefundAppParams(multisigAddress, balanceRefundRecipientIdentifer, proposedToIdentifier, tokenAddress = constants_1.AddressZero) {
const provider = new providers_1.JsonRpcProvider(global["ganacheURL"]);
let threshold;
if (tokenAddress === constants_1.AddressZero) {
threshold = await provider.getBalance(multisigAddress);
}
else {
const contract = new ethers_1.Contract(tokenAddress, DolphinCoin_json_1.default.abi, provider);
threshold = await contract.balanceOf(multisigAddress);
}
return {
abiEncodings: {
actionEncoding: undefined,
stateEncoding: `tuple(address recipient, address multisig, uint256 threshold, address tokenAddress)`
},
appDefinition: CoinBalanceRefundApp,
initialState: {
multisig: multisigAddress,
recipient: machine_1.xkeyKthAddress(balanceRefundRecipientIdentifer, 0),
threshold,
tokenAddress
},
initiatorDeposit: constants_1.Zero,
initiatorDepositTokenAddress: tokenAddress,
outcomeType: cf_types_1.OutcomeType.SINGLE_ASSET_TWO_PARTY_COIN_TRANSFER,
proposedToIdentifier,
responderDeposit: constants_1.Zero,
responderDepositTokenAddress: tokenAddress,
timeout: constants_1.Zero
};
}
exports.getProposeCoinBalanceRefundAppParams = getProposeCoinBalanceRefundAppParams;
async function deposit(node, multisigAddress, amount = constants_1.One, proposedToNode, tokenAddress) {
const proposeParams = await getProposeCoinBalanceRefundAppParams(multisigAddress, node.publicIdentifier, proposedToNode.publicIdentifier, tokenAddress);
await new Promise(async (resolve) => {
proposedToNode.once(src_1.NODE_EVENTS.PROPOSE_INSTALL, (msg) => {
resolve();
});
node.rpcRouter.dispatch({
id: Date.now(),
methodName: cf_types_1.Node.RpcMethodName.PROPOSE_INSTALL,
parameters: proposeParams
});
});
const depositReq = constructDepositRpc(multisigAddress, amount, tokenAddress);

@@ -187,5 +257,5 @@ return new Promise(async (resolve) => {

data: {
value: amount,
value: amount
}
}, ['data.txHash']);
}, ["data.txHash"]);
});

@@ -209,12 +279,11 @@ await node.rpcRouter.dispatch(depositReq);

function constructDepositRpc(multisigAddress, amount, tokenAddress) {
return src_1.jsonRpcDeserialize({
return {
id: Date.now(),
method: cf_types_1.Node.RpcMethodName.DEPOSIT,
params: {
methodName: cf_types_1.Node.RpcMethodName.DEPOSIT,
parameters: {
multisigAddress,
amount,
tokenAddress
},
jsonrpc: "2.0"
});
}
};
}

@@ -230,6 +299,6 @@ exports.constructDepositRpc = constructDepositRpc;

function constructWithdrawRpc(multisigAddress, amount, tokenAddress = constants_2.CONVENTION_FOR_ETH_TOKEN_ADDRESS, recipient) {
return src_1.jsonRpcDeserialize({
return {
id: Date.now(),
method: cf_types_1.Node.RpcMethodName.WITHDRAW,
params: {
methodName: cf_types_1.Node.RpcMethodName.WITHDRAW,
parameters: {
tokenAddress,

@@ -239,27 +308,24 @@ multisigAddress,

recipient
},
jsonrpc: "2.0"
});
}
};
}
exports.constructWithdrawRpc = constructWithdrawRpc;
function constructInstallRpc(appInstanceId) {
return src_1.jsonRpcDeserialize({
return {
id: Date.now(),
method: cf_types_1.Node.RpcMethodName.INSTALL,
params: {
methodName: cf_types_1.Node.RpcMethodName.INSTALL,
parameters: {
appInstanceId
},
jsonrpc: "2.0"
});
}
};
}
exports.constructInstallRpc = constructInstallRpc;
function constructRejectInstallRpc(appInstanceId) {
return src_1.jsonRpcDeserialize({
return {
id: Date.now(),
method: cf_types_1.Node.RpcMethodName.REJECT_INSTALL,
params: {
methodName: cf_types_1.Node.RpcMethodName.REJECT_INSTALL,
parameters: {
appInstanceId
},
jsonrpc: "2.0"
});
}
};
}

@@ -269,7 +335,6 @@ exports.constructRejectInstallRpc = constructRejectInstallRpc;

const { outcomeType } = getAppContext(appDefinition, initialState);
return src_1.jsonRpcDeserialize({
return {
id: Date.now(),
method: cf_types_1.Node.RpcMethodName.PROPOSE_INSTALL,
jsonrpc: "2.0",
params: {
methodName: cf_types_1.Node.RpcMethodName.PROPOSE_INSTALL,
parameters: {
proposedToIdentifier,

@@ -286,8 +351,8 @@ initiatorDeposit,

}
});
};
}
exports.constructAppProposalRpc = constructAppProposalRpc;
function constructInstallVirtualRpc(appInstanceId, intermediaryIdentifier) {
return src_1.jsonRpcDeserialize({
params: {
return {
parameters: {
appInstanceId,

@@ -297,5 +362,4 @@ intermediaryIdentifier

id: Date.now(),
method: cf_types_1.Node.RpcMethodName.INSTALL_VIRTUAL,
jsonrpc: "2.0"
});
methodName: cf_types_1.Node.RpcMethodName.INSTALL_VIRTUAL
};
}

@@ -305,8 +369,7 @@ exports.constructInstallVirtualRpc = constructInstallVirtualRpc;

const installProposalParams = constructAppProposalRpc(proposedToIdentifier, appDefinition, abiEncodings, initialState, initiatorDeposit, initiatorDepositTokenAddress, responderDeposit, responderDepositTokenAddress).parameters;
return src_1.jsonRpcDeserialize({
params: installProposalParams,
return {
parameters: installProposalParams,
id: Date.now(),
method: cf_types_1.Node.RpcMethodName.PROPOSE_INSTALL,
jsonrpc: "2.0"
});
methodName: cf_types_1.Node.RpcMethodName.PROPOSE_INSTALL
};
}

@@ -330,15 +393,14 @@ exports.constructVirtualProposalRpc = constructVirtualProposalRpc;

function constructGetStateRpc(appInstanceId) {
return src_1.jsonRpcDeserialize({
params: {
return {
parameters: {
appInstanceId
},
id: Date.now(),
method: cf_types_1.Node.RpcMethodName.GET_STATE,
jsonrpc: "2.0"
});
methodName: cf_types_1.Node.RpcMethodName.GET_STATE
};
}
exports.constructGetStateRpc = constructGetStateRpc;
function constructTakeActionRpc(appInstanceId, action) {
return src_1.jsonRpcDeserialize({
params: {
return {
parameters: {
appInstanceId,

@@ -348,30 +410,27 @@ action

id: Date.now(),
jsonrpc: "2.0",
method: cf_types_1.Node.RpcMethodName.TAKE_ACTION
});
methodName: cf_types_1.Node.RpcMethodName.TAKE_ACTION
};
}
exports.constructTakeActionRpc = constructTakeActionRpc;
function constructGetAppsRpc() {
return src_1.jsonRpcDeserialize({
params: {},
return {
parameters: {},
id: Date.now(),
method: cf_types_1.Node.RpcMethodName.GET_APP_INSTANCES,
jsonrpc: "2.0"
});
methodName: cf_types_1.Node.RpcMethodName.GET_APP_INSTANCES
};
}
exports.constructGetAppsRpc = constructGetAppsRpc;
function constructUninstallRpc(appInstanceId) {
return src_1.jsonRpcDeserialize({
params: {
return {
parameters: {
appInstanceId
},
id: Date.now(),
jsonrpc: "2.0",
method: cf_types_1.Node.RpcMethodName.UNINSTALL
});
methodName: cf_types_1.Node.RpcMethodName.UNINSTALL
};
}
exports.constructUninstallRpc = constructUninstallRpc;
function constructUninstallVirtualRpc(appInstanceId, intermediaryIdentifier) {
return src_1.jsonRpcDeserialize({
params: {
return {
parameters: {
appInstanceId,

@@ -381,12 +440,9 @@ intermediaryIdentifier

id: Date.now(),
jsonrpc: "2.0",
method: cf_types_1.Node.RpcMethodName.UNINSTALL_VIRTUAL
});
methodName: cf_types_1.Node.RpcMethodName.UNINSTALL_VIRTUAL
};
}
exports.constructUninstallVirtualRpc = constructUninstallVirtualRpc;
async function collateralizeChannel(multisigAddress, node1, node2, amount = constants_1.One, tokenAddress = constants_2.CONVENTION_FOR_ETH_TOKEN_ADDRESS) {
await deposit(node1, multisigAddress, amount, tokenAddress);
if (!node2)
return;
await deposit(node2, multisigAddress, amount, tokenAddress);
await deposit(node1, multisigAddress, amount, node2, tokenAddress);
await deposit(node2, multisigAddress, amount, node1, tokenAddress);
}

@@ -403,5 +459,5 @@ exports.collateralizeChannel = collateralizeChannel;

owners: sortedOwners,
counterpartyXpub: nodeA.publicIdentifier,
counterpartyXpub: nodeA.publicIdentifier
}
}, ['data.multisigAddress']);
}, ["data.multisigAddress"]);
expect(await getInstalledAppInstances(nodeB)).toEqual([]);

@@ -416,5 +472,5 @@ resolve(msg.data.multisigAddress);

owners: sortedOwners,
counterpartyXpub: nodeB.publicIdentifier,
counterpartyXpub: nodeB.publicIdentifier
}
}, ['data.multisigAddress']);
}, ["data.multisigAddress"]);
});

@@ -458,3 +514,3 @@ await getMultisigCreationAddress(nodeA, [

nodeC.on(src_1.NODE_EVENTS.PROPOSE_INSTALL, async (msg) => {
const { appInstanceId, params, } = await proposal;
const { appInstanceId, params } = await proposal;
const { data: { appInstanceId: eventAppInstanceId } } = msg;

@@ -473,3 +529,3 @@ if (eventAppInstanceId === appInstanceId) {

type: src_1.NODE_EVENTS.INSTALL_VIRTUAL,
data: { params: { appInstanceId } },
data: { params: { appInstanceId } }
});

@@ -476,0 +532,0 @@ resolve(appInstanceId);

{
"name": "@connext/cf-core",
"version": "1.2.12",
"version": "1.2.13",
"main": "dist/src/index.js",

@@ -22,3 +22,2 @@ "iife": "dist/src/index.iife.js",

"@connext/cf-funding-protocol-contracts": "0.4.1",
"@connext/types": "1.2.12",
"@counterfactual/cf-adjudicator-contracts": "0.0.9",

@@ -37,2 +36,4 @@ "@counterfactual/cf-funding-protocol-contracts": "0.0.12",

"@babel/plugin-proposal-object-rest-spread": "7.6.2",
"@connext/cf-types": "1.2.13",
"@connext/types": "1.2.13",
"@counterfactual/local-ganache-server": "0.0.10",

@@ -39,0 +40,0 @@ "@counterfactual/postgresql-node-connector": "0.0.8",

@@ -9,5 +9,5 @@ import { defaultAbiCoder, keccak256 } from "ethers/utils";

["uint256", "address[]"],
[appIdentity.channelNonce, appIdentity.participants],
),
[appIdentity.channelNonce, appIdentity.participants]
)
);
}

@@ -12,2 +12,5 @@ import { BigNumber } from "ethers/utils";

export const COIN_BALANCE_NOT_PROPOSED =
"No coin balance refund app proposed in channel.";
export const BALANCE_REFUND_APP_ALREADY_INSTALLED =

@@ -14,0 +17,0 @@ "Balance refund app is installed, please uninstall first.";

@@ -15,3 +15,4 @@ import { Contract } from "ethers";

INSUFFICIENT_ERC20_FUNDS_TO_DEPOSIT,
INSUFFICIENT_FUNDS
INSUFFICIENT_FUNDS,
COIN_BALANCE_NOT_PROPOSED
} from "../../errors";

@@ -50,6 +51,20 @@

if (channel.hasAppInstanceOfKind(networkContext.CoinBalanceRefundApp)) {
if (
channel.hasBalanceRefundAppInstance(
networkContext.CoinBalanceRefundApp,
tokenAddress
)
) {
throw Error(CANNOT_DEPOSIT);
}
if (
!channel.hasProposedBalanceRefundAppInstance(
networkContext.CoinBalanceRefundApp,
tokenAddress
)
) {
throw Error(COIN_BALANCE_NOT_PROPOSED);
}
const address = await requestHandler.getSignerAddress();

@@ -120,15 +135,15 @@

const multisigBalance =
params.tokenAddress === CONVENTION_FOR_ETH_TOKEN_ADDRESS
? await provider.getBalance(multisigAddress)
: await new Contract(
tokenAddress!,
ERC20.abi,
provider
).functions.balanceOf(multisigAddress);
params.tokenAddress === CONVENTION_FOR_ETH_TOKEN_ADDRESS
? await provider.getBalance(multisigAddress)
: await new Contract(
tokenAddress!,
ERC20.abi,
provider
).functions.balanceOf(multisigAddress);
return {
multisigBalance,
tokenAddress: params.tokenAddress!,
tokenAddress: params.tokenAddress!
};
}
}

@@ -12,3 +12,7 @@ import { Contract } from "ethers";

import { ERC20 } from "../../../contracts";
import { InstallProtocolParams, Protocol, xkeyKthAddress } from "../../../machine";
import {
InstallProtocolParams,
Protocol,
xkeyKthAddress
} from "../../../machine";
import { StateChannel } from "../../../models";

@@ -71,3 +75,3 @@ import { RequestHandler } from "../../../request-handler";

const InstallProtocolParams: InstallProtocolParams = {
const installProtocolParams: InstallProtocolParams = {
initialState: depositContext.initialState,

@@ -96,3 +100,3 @@ initiatorXpub: publicIdentifier,

stateChannelsMap,
InstallProtocolParams
installProtocolParams
);

@@ -106,3 +110,8 @@ }

const { multisigAddress, amount, tokenAddress } = params;
const { provider, blocksNeededForConfirmation, outgoing, publicIdentifier } = requestHandler;
const {
provider,
blocksNeededForConfirmation,
outgoing,
publicIdentifier
} = requestHandler;

@@ -139,3 +148,3 @@ const signer = await requestHandler.getSigner();

type: NODE_EVENTS.DEPOSIT_FAILED,
data: { errors, params },
data: { errors, params }
};

@@ -162,3 +171,3 @@ if (e.toString().includes("reject") || e.toString().includes("denied")) {

txHash: txResponse!.hash
},
}
});

@@ -181,3 +190,3 @@

const { multisigAddress } = params;
const { multisigAddress, tokenAddress } = params;

@@ -194,5 +203,16 @@ const { CoinBalanceRefundApp } = networkContext;

const refundApp = stateChannel.getAppInstanceOfKind(CoinBalanceRefundApp);
let refundApp;
try {
refundApp = stateChannel.getBalanceRefundAppInstance(
CoinBalanceRefundApp,
tokenAddress
);
} catch (e) {
if (e.message.includes(`No CoinBalanceRefund app instance`)) {
// no need to unintall, already uninstalled
return;
}
}
const stateChannelsMap = await protocolRunner.initiateProtocol(
await protocolRunner.initiateProtocol(
Protocol.Uninstall,

@@ -199,0 +219,0 @@ // https://github.com/counterfactual/monorepo/issues/747

@@ -59,5 +59,11 @@ import ERC20 from "@counterfactual/cf-funding-protocol-contracts/expected-build-artifacts/ERC20.json";

if (channel.hasAppInstanceOfKind(networkContext.CoinBalanceRefundApp)) {
const balanceRefundApp = channel.getAppInstanceOfKind(
networkContext.CoinBalanceRefundApp
if (
channel.hasBalanceRefundAppInstance(
networkContext.CoinBalanceRefundApp,
params.tokenAddress
)
) {
const balanceRefundApp = channel.getBalanceRefundAppInstance(
networkContext.CoinBalanceRefundApp,
params.tokenAddress
);

@@ -72,4 +78,7 @@ // if app is already pointing at us and the multisig balance has not changed,

return {
multisigBalance,
recipient: freeBalanceAddress
freeBalance: channel
.getFreeBalanceClass()
.withTokenAddress(params.tokenAddress),
recipient: freeBalanceAddress,
tokenAddress: params.tokenAddress
};

@@ -86,6 +95,9 @@ }

return {
multisigBalance,
recipient: freeBalanceAddress
freeBalance: channel
.getFreeBalanceClass()
.withTokenAddress(params.tokenAddress),
recipient: freeBalanceAddress,
tokenAddress: params.tokenAddress
};
}
}

@@ -35,3 +35,4 @@ import ERC20 from "@counterfactual/cf-funding-protocol-contracts/expected-build-artifacts/ERC20.json";

const { multisigAddress } = params;
const tokenAddress = params.tokenAddress || CONVENTION_FOR_ETH_TOKEN_ADDRESS;
const tokenAddress =
params.tokenAddress || CONVENTION_FOR_ETH_TOKEN_ADDRESS;

@@ -50,3 +51,3 @@ let multisigBalance: BigNumber;

multisigBalance,
tokenAddress,
tokenAddress
};

@@ -60,6 +61,6 @@ }

// unused params to make types happy
tokenAddress: CONVENTION_FOR_ETH_TOKEN_ADDRESS,
tokenAddress,
amount: Zero
},
await provider.getBlockNumber(),
await provider.getBlockNumber()
);

@@ -69,5 +70,5 @@

multisigBalance,
tokenAddress,
tokenAddress
};
}
}

@@ -0,1 +1,2 @@

import { JsonRpcProvider, TransactionResponse } from "ethers/providers";

@@ -30,4 +31,10 @@ import { jsonRpcMethod } from "rpc-server";

const tokenAddress =
params.tokenAddress || CONVENTION_FOR_ETH_TOKEN_ADDRESS;
if (
stateChannel.hasAppInstanceOfKind(networkContext.CoinBalanceRefundApp)
stateChannel.hasBalanceRefundAppInstance(
networkContext.CoinBalanceRefundApp,
tokenAddress
)
) {

@@ -37,5 +44,2 @@ throw Error(CANNOT_WITHDRAW);

const tokenAddress =
params.tokenAddress || CONVENTION_FOR_ETH_TOKEN_ADDRESS;
const senderBalance = stateChannel

@@ -42,0 +46,0 @@ .getFreeBalanceClass()

import { BigNumber } from "ethers/utils";
import { StateChannelJSON, SingleAssetTwoPartyIntermediaryAgreement } from "@connext/types";
import {
StateChannelJSON,
SingleAssetTwoPartyIntermediaryAgreement
} from "@connext/types";
import { flip, flipTokenIndexedBalances } from "../ethereum/utils/free-balance-app";
import {
flip,
flipTokenIndexedBalances
} from "../ethereum/utils/free-balance-app";
import { xkeyKthAddress } from "../machine/xkeys";

@@ -16,8 +22,9 @@ import { Store } from "../store";

FreeBalanceClass,
TokenIndexedCoinTransferMap,
TokenIndexedCoinTransferMap
} from "./free-balance";
import { CONVENTION_FOR_ETH_TOKEN_ADDRESS } from "../constants";
// TODO: Hmmm this code should probably be somewhere else?
export const HARD_CODED_ASSUMPTIONS = {
freeBalanceDefaultTimeout: 172800,
freeBalanceDefaultTimeout: 172800
};

@@ -132,5 +139,69 @@

throw Error(
`Either 0 or more than 1 AppInstance of addr ${address} exists on channel: ${this.multisigAddress}`
);
}
return appInstances[0];
}
public getAppInstancesOfKind(address: string) {
const appInstances = Array.from(this.appInstances.values()).filter(
(appInstance: AppInstance) => {
return appInstance.appInterface.addr === address;
}
);
if (appInstances.length === 0) {
throw Error(
`No AppInstance of addr ${address} exists on channel: ${this.multisigAddress}`
);
}
return appInstances;
}
public hasBalanceRefundAppInstance(
balanceRefundAppDefinitionAddress: string,
tokenAddress: string
) {
return (
Array.from(this.appInstances.values()).filter(
(appInstance: AppInstance) =>
appInstance.appInterface.addr === balanceRefundAppDefinitionAddress &&
appInstance.latestState["tokenAddress"] === tokenAddress
).length > 0
);
}
public hasProposedBalanceRefundAppInstance(
balanceRefundAppDefinitionAddress: string,
tokenAddress: string
) {
return (
Array.from(this.proposedAppInstances.values()).filter(
(appInstance: AppInstanceProposal) =>
appInstance.appDefinition === balanceRefundAppDefinitionAddress &&
appInstance.initialState["tokenAddress"] === tokenAddress
).length > 0
);
}
public getBalanceRefundAppInstance(
balanceRefundAppDefinitionAddress: string,
tokenAddress: string = CONVENTION_FOR_ETH_TOKEN_ADDRESS
) {
const appInstances = this.getAppInstancesOfKind(
balanceRefundAppDefinitionAddress
).filter(
(appInstance: AppInstance) =>
appInstance.latestState["tokenAddress"] === tokenAddress
);
if (appInstances.length === 0) {
throw Error(
`No CoinBalanceRefund app instance of tokenAddress ${tokenAddress} exists on channel: ${this.multisigAddress}`
);
}
if (appInstances.length > 1) {
throw Error(
`More than 1 CoinBalanceRefund app instance of tokenAddress ${tokenAddress} exists on channel: ${this.multisigAddress}`
);
}
return appInstances[0];

@@ -437,3 +508,2 @@ }

/// Add modified FB and new AppInstance to appInstances
const appInstances = new Map<string, AppInstance>(

@@ -446,3 +516,3 @@ this.appInstances.entries()

// If the app is in the proposed apps, make sure it is
// removed (otherwise channel is persisted with proposal +
// removed (otherwise channel is persisted with proposal +
// installed application after protocol)

@@ -545,19 +615,17 @@ // NOTE: `deposit` will install an app, but never propose it

new Map(
[...Object.values(dropNulls(json.proposedAppInstances) || [])].map((proposal): [
string,
AppInstanceProposal
] => {
return [proposal[0], proposal[1]];
})
[...Object.values(dropNulls(json.proposedAppInstances) || [])].map(
(proposal): [string, AppInstanceProposal] => {
return [proposal[0], proposal[1]];
}
)
),
new Map(
[...Object.values(dropNulls(json.appInstances) || [])].map((appInstanceEntry): [
string,
AppInstance
] => {
return [
appInstanceEntry[0],
AppInstance.fromJson(appInstanceEntry[1])
];
})
[...Object.values(dropNulls(json.appInstances) || [])].map(
(appInstanceEntry): [string, AppInstance] => {
return [
appInstanceEntry[0],
AppInstance.fromJson(appInstanceEntry[1])
];
}
)
),

@@ -571,3 +639,7 @@ new Map(json.singleAssetTwoPartyIntermediaryAgreements || []),

} catch (e) {
throw new Error(`could not create state channel from json: ${prettyPrintObject(json)}. Error: ${e}`);
throw new Error(
`could not create state channel from json: ${prettyPrintObject(
json
)}. Error: ${e}`
);
}

@@ -574,0 +646,0 @@ }

@@ -51,3 +51,3 @@ import { defaultAbiCoder, keccak256 } from "ethers/utils";

]);
const appInstanceProposal: AppInstanceProposal = {

@@ -54,0 +54,0 @@ appDefinition,

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

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

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

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc