Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client fix for evaluating ETH balance across networks #1001

Merged
merged 15 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 71 additions & 31 deletions packages/sdk/src/channelsWithEntitlements.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import {
expectUserCanJoin,
everyoneMembershipStruct,
linkWallets,
getXchainSupportedRpcUrlsForTesting,
getXchainConfigForTesting,
erc20CheckOp,
customCheckOp,
nativeCoinBalanceCheckOp,
setupChannelWithCustomRole,
expectUserCanJoinChannel,
expectUserCannotJoinChannel,
ethBalanceCheckOp,
} from './util.test'
import { MembershipOp } from '@river-build/proto'
import { dlog } from '@river-build/dlog'
Expand All @@ -43,9 +43,10 @@ import {
import { make_MemberPayload_KeySolicitation } from './types'

const log = dlog('csb:test:channelsWithEntitlements')
const twoEth = BigInt(2e18)
const oneEth = BigInt(1e18)
const oneHalfEth = BigInt(5e17)
const oneEth = oneHalfEth * BigInt(2)
const twoEth = oneEth * BigInt(2)
const gtTwoEth = twoEth + BigInt(1)

describe('channelsWithEntitlements', () => {
test('User who satisfies only one role ruledata requirement can join channel', async () => {
Expand Down Expand Up @@ -374,7 +375,7 @@ describe('channelsWithEntitlements', () => {
channelId!,
alice.userId,
Permission.Read,
getXchainSupportedRpcUrlsForTesting(),
getXchainConfigForTesting(),
),
).resolves.toBeFalsy()

Expand Down Expand Up @@ -1113,15 +1114,13 @@ describe('channelsWithEntitlements', () => {
log('Done', Date.now() - doneStart)
})

test('native coin balance gate pass', async () => {
const ruleData = treeToRuleData(nativeCoinBalanceCheckOp(oneEth))
test('eth balance gate pass', async () => {
const ruleData = treeToRuleData(ethBalanceCheckOp(oneEth))

const { alice, bob, alicesWallet, aliceSpaceDapp, spaceId, channelId } =
await setupChannelWithCustomRole([], ruleData)

await TestEthBalance.setBalance(alicesWallet.address as Address, oneEth)
const balance = await TestEthBalance.getBalance(alicesWallet.address as Address)
expect(balance).toEqual(oneEth)
await Promise.all([TestEthBalance.setBaseBalance(alicesWallet.address as Address, oneEth)])

log('expect that alice can join the channel')
await expectUserCanJoinChannel(alice, aliceSpaceDapp, spaceId, channelId!)
Expand All @@ -1133,13 +1132,36 @@ describe('channelsWithEntitlements', () => {
log('Done', Date.now() - doneStart)
})

test('native coin balance gate fail', async () => {
const ruleData = treeToRuleData(nativeCoinBalanceCheckOp(oneEth))
test('eth balance gate pass - across networks', async () => {
const ruleData = treeToRuleData(ethBalanceCheckOp(oneEth))

const { alice, bob, alicesWallet, aliceSpaceDapp, spaceId, channelId } =
await setupChannelWithCustomRole([], ruleData)

await TestEthBalance.setBalance(alicesWallet.address as Address, 0n)
await Promise.all([
TestEthBalance.setBaseBalance(alicesWallet.address as Address, oneHalfEth),
TestEthBalance.setRiverBalance(alicesWallet.address as Address, oneHalfEth),
])

log('expect that alice can join the channel')
await expectUserCanJoinChannel(alice, aliceSpaceDapp, spaceId, channelId!)

// kill the clients
const doneStart = Date.now()
await bob.stopSync()
await alice.stopSync()
log('Done', Date.now() - doneStart)
})

test('eth balance gate fail', async () => {
const ruleData = treeToRuleData(ethBalanceCheckOp(oneEth))

const { alice, bob, alicesWallet, aliceSpaceDapp, spaceId, channelId } =
await setupChannelWithCustomRole([], ruleData)

// alice's base wallet may need to be explicitly set to zero to compensate for wallet funding in
// initialization methods.
await Promise.all([TestEthBalance.setBaseBalance(alicesWallet.address as Address, 0n)])

log('expect that alice cannot join the channel (has no ETH)')
await expectUserCannotJoinChannel(alice, aliceSpaceDapp, spaceId, channelId!)
Expand All @@ -1151,8 +1173,8 @@ describe('channelsWithEntitlements', () => {
log('Done', Date.now() - doneStart)
})

test('native coin balance gate join pass - join as root, linked wallet entitled', async () => {
const ruleData = treeToRuleData(nativeCoinBalanceCheckOp(oneEth))
test('eth balance gate join pass - join as root, linked wallet entitled', async () => {
const ruleData = treeToRuleData(ethBalanceCheckOp(oneEth))
const {
alice,
bob,
Expand All @@ -1168,14 +1190,19 @@ describe('channelsWithEntitlements', () => {
// Link carol's wallet to alice's as root
await linkWallets(aliceSpaceDapp, aliceProvider.wallet, carolProvider.wallet)

// Set wallet balances to 0
await TestEthBalance.setBalance(carolsWallet.address as Address, 0n)
await TestEthBalance.setBalance(alicesWallet.address as Address, 0n)
// Explicitly set wallet balances to 0
await Promise.all([
TestEthBalance.setBaseBalance(carolsWallet.address as Address, 0n),
TestEthBalance.setBaseBalance(alicesWallet.address as Address, 0n),
])

// Validate alice cannot join the channel
await expectUserCannotJoinChannel(alice, aliceSpaceDapp, spaceId, channelId!)

await TestEthBalance.setBalance(carolsWallet.address as Address, oneEth)
await Promise.all([
TestEthBalance.setBaseBalance(carolsWallet.address as Address, oneHalfEth),
TestEthBalance.setRiverBalance(carolsWallet.address as Address, oneHalfEth),
])

// Wait 2 seconds for the negative auth cache to expire
await new Promise((f) => setTimeout(f, 2000))
Expand All @@ -1190,8 +1217,8 @@ describe('channelsWithEntitlements', () => {
log('Done', Date.now() - doneStart)
})

test('native coin balance gated join pass - join as linked wallet, assets in root wallet', async () => {
const ruleData = treeToRuleData(nativeCoinBalanceCheckOp(oneEth))
test('eth balance gated join pass - join as linked wallet, assets in root wallet', async () => {
const ruleData = treeToRuleData(ethBalanceCheckOp(twoEth))
const {
alice,
bob,
Expand All @@ -1209,8 +1236,13 @@ describe('channelsWithEntitlements', () => {
await linkWallets(carolSpaceDapp, carolProvider.wallet, aliceProvider.wallet)

log("Setting carol and alice's wallet balances to 1ETH and 0, respectively")
await TestEthBalance.setBalance(carolsWallet.address as Address, oneEth)
await TestEthBalance.setBalance(alicesWallet.address as Address, 0n)
// Carol's cumulative balance across wallets: 2ETH
// Alice's cumulative balance: 0
await Promise.all([
TestEthBalance.setBaseBalance(carolsWallet.address as Address, oneEth),
TestEthBalance.setRiverBalance(carolsWallet.address as Address, oneEth),
TestEthBalance.setBaseBalance(alicesWallet.address as Address, 0n),
])

log('expect that alice can join the channel')
// Validate alice can join the channel
Expand All @@ -1223,8 +1255,8 @@ describe('channelsWithEntitlements', () => {
log('Done', Date.now() - doneStart)
})

test('native coin balance gate join pass - assets across wallets', async () => {
const ruleData = treeToRuleData(nativeCoinBalanceCheckOp(oneEth))
test('eth balance gate join pass - assets across wallets and networks', async () => {
const ruleData = treeToRuleData(ethBalanceCheckOp(twoEth))
const {
alice,
bob,
Expand All @@ -1241,8 +1273,12 @@ describe('channelsWithEntitlements', () => {
await linkWallets(aliceSpaceDapp, aliceProvider.wallet, carolProvider.wallet)

// Set wallet balances to 0
await TestEthBalance.setBalance(carolsWallet.address as Address, oneHalfEth)
await TestEthBalance.setBalance(alicesWallet.address as Address, oneHalfEth)
await Promise.all([
TestEthBalance.setBaseBalance(carolsWallet.address as Address, oneHalfEth),
TestEthBalance.setBaseBalance(alicesWallet.address as Address, oneHalfEth),
TestEthBalance.setRiverBalance(carolsWallet.address as Address, oneHalfEth),
TestEthBalance.setRiverBalance(alicesWallet.address as Address, oneHalfEth),
])

// Validate alice can join the channel
log('expect that alice can join the channel')
Expand All @@ -1255,8 +1291,8 @@ describe('channelsWithEntitlements', () => {
log('Done', Date.now() - doneStart)
})

test('native coin balance gate join fail - insufficient assets across wallets', async () => {
const ruleData = treeToRuleData(nativeCoinBalanceCheckOp(twoEth))
test('eth balance gate join fail - insufficient assets across wallets', async () => {
const ruleData = treeToRuleData(ethBalanceCheckOp(gtTwoEth))
const {
alice,
bob,
Expand All @@ -1275,8 +1311,12 @@ describe('channelsWithEntitlements', () => {
await linkWallets(aliceSpaceDapp, aliceProvider.wallet, carolProvider.wallet)

// Set wallet balances to 0
await TestEthBalance.setBalance(carolsWallet.address as Address, oneHalfEth)
await TestEthBalance.setBalance(alicesWallet.address as Address, oneHalfEth)
await Promise.all([
TestEthBalance.setBaseBalance(carolsWallet.address as Address, oneHalfEth),
TestEthBalance.setBaseBalance(alicesWallet.address as Address, oneHalfEth),
TestEthBalance.setRiverBalance(carolsWallet.address as Address, oneHalfEth),
TestEthBalance.setRiverBalance(alicesWallet.address as Address, oneHalfEth),
])

log('expect neither alice nor carol can join the channel')
await expectUserCannotJoinChannel(alice, aliceSpaceDapp, spaceId, channelId!)
Expand Down
Loading
Loading