Skip to content

Commit

Permalink
Merge pull request #1228 from XYOracleNetwork/feature/bound-witness-h…
Browse files Browse the repository at this point in the history
…elpers

BoundWitness Helpers
  • Loading branch information
JoelBCarter authored Sep 24, 2024
2 parents ba7003c + cad3526 commit c626847
Show file tree
Hide file tree
Showing 14 changed files with 310 additions and 2 deletions.
30 changes: 29 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,40 @@
"--forceExit",
"--runInBand",
"--testTimeout=120000",
"packages/modules/packages/diviner/packages/payloadpointer/packages/memory/src/spec/Diviner.payloadPointer.schema.spec.ts"
"packages/protocol/packages/boundwitness/packages/validator/src/lib/addresses/spec/addressesContainsAll.spec.ts"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"cwd": "${workspaceFolder}",
"envFile": "${workspaceFolder}/.env"
},
{
"name": "Vite",
"request": "launch",
"type": "node",
"program": "${workspaceFolder}/node_modules/vitest/vitest.mjs",
"args": [
"--run",
"--inspect-brk",
"--no-file-parallelism",
"packages/protocol/packages/boundwitness/packages/validator/src/lib/addresses/spec/addressesContainsAny.spec.ts"
],
"sourceMaps": true,
"resolveSourceMapLocations": [
"${workspaceFolder}/**",
"**/node_modules/**"
],
"outFiles": [
"${workspaceFolder}/dist/**/*.*",
"${workspaceFolder}/node_modules/**/*.*"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"cwd": "${workspaceRoot}",
"env": {
"NODE_ENV": "test"
},
"envFile": "${workspaceRoot}/.env",
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"types": "dist/neutral/index.d.ts",
"dependencies": {
"@xylabs/arraybuffer": "^4.0.9",
"@xylabs/hex": "^4.0.10",
"@xylabs/lodash": "^4.0.9",
"@xylabs/typeof": "^4.0.9",
"@xyo-network/account": "workspace:^",
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './lib/index.ts'
export * from './Validator.ts'
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { Address } from '@xylabs/hex'
import type { BoundWitness } from '@xyo-network/boundwitness-model'

/**
* Checks if the boundwitness contains the addresses
* @param bw The boundwitness to check
* @param addresses The address to check for
* @returns True if the boundwitness contains the addresses
*/
export const addressesContainsAddress = (bw: BoundWitness, address: Address): boolean => {
return bw.addresses?.includes(address)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { Address } from '@xylabs/hex'
import type { BoundWitness } from '@xyo-network/boundwitness-model'

/**
* Checks if the boundwitness contains all of the addresses
* @param bw The boundwitness to check
* @param addresses The addresses to check for
* @returns True if the boundwitness contains all of the addresses
*/
export const addressesContainsAll = (bw: BoundWitness, addresses: Address[]): boolean => {
return addresses.every(address => bw.addresses?.includes(address))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Address } from '@xylabs/hex'
import type { BoundWitness } from '@xyo-network/boundwitness-model'

/**
* Checks if the boundwitness contains any of the addresses. If the addresses array
* is empty, it will return true. This is to match the behavior or addressesContainsAll
* which will return true if the addresses array is empty.
* @param bw The boundwitness to check
* @param addresses The addresses to check for
* @returns True if the boundwitness contains any of the addresses
*/
export const addressesContainsAny = (bw: BoundWitness, addresses: Address[]): boolean => {
if (addresses.length === 0) return true
return addresses.some(address => bw.addresses?.includes(address))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './addressesContainsAddress.ts'
export * from './addressesContainsAll.ts'
export * from './addressesContainsAny.ts'
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import type { WalletInstance } from '@xyo-network/account'
import { HDWallet } from '@xyo-network/account'
import { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'

import { addressesContainsAddress } from '../addressesContainsAddress.ts'

describe('addressesContainsAddress', () => {
const payload = { schema: 'network.xyo.test', value: Date.now() }
let oneWallet: WalletInstance[] = []
let twoWallets: WalletInstance[] = []

beforeAll(async () => {
oneWallet = [await HDWallet.random()]
twoWallets = [await HDWallet.random(), await HDWallet.random()]
})

const buildBoundWitness = async (signers: WalletInstance[]) => {
const [bw] = await new BoundWitnessBuilder().signers(signers).payload(payload).build()
return bw
}

describe('returns true', () => {
it('with a single wallet and the address is present', async () => {
const bw = await buildBoundWitness(oneWallet)
const address = oneWallet[0].address
expect(addressesContainsAddress(bw, address)).toBeTrue()
})

it('with multiple wallets and the address is present', async () => {
const bw = await buildBoundWitness(twoWallets)
const address = twoWallets[0].address
expect(addressesContainsAddress(bw, address)).toBeTrue()
})

it('with extra signers and the address is present', async () => {
const extraSigners = [...twoWallets, await HDWallet.random()]
const bw = await buildBoundWitness(extraSigners)
const address = twoWallets[1].address
expect(addressesContainsAddress(bw, address)).toBeTrue()
})
})

describe('returns false', () => {
it('with no signers', async () => {
const [bw] = await new BoundWitnessBuilder().payload(payload).build()
const address = oneWallet[0].address
expect(addressesContainsAddress(bw, address)).toBeFalse()
})

it('with a single wallet but a different address is checked', async () => {
const bw = await buildBoundWitness(oneWallet)
const randomAddress = (await HDWallet.random()).address
expect(addressesContainsAddress(bw, randomAddress)).toBeFalse()
})

it('with multiple wallets but a non-existing address is checked', async () => {
const bw = await buildBoundWitness(twoWallets)
const randomAddress = (await HDWallet.random()).address
expect(addressesContainsAddress(bw, randomAddress)).toBeFalse()
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import type { Address } from '@xylabs/hex'
import type { WalletInstance } from '@xyo-network/account'
import { HDWallet } from '@xyo-network/account'
import { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'

import { addressesContainsAll } from '../addressesContainsAll.ts'

describe('addressesContainsAll', () => {
const payload = { schema: 'network.xyo.test', value: Date.now() }
let oneWallet: WalletInstance[] = []
let twoWallets: WalletInstance[] = []

beforeAll(async () => {
oneWallet = [await HDWallet.random()]
twoWallets = [await HDWallet.random(), await HDWallet.random()]
})

const buildBoundWitness = async (signers: WalletInstance[]) => {
const [bw] = await new BoundWitnessBuilder().signers(signers).payload(payload).build()
return bw
}

describe('returns true', () => {
const cases: [string, () => WalletInstance[]][] = [
['with no wallets', () => []],
['with single wallet', () => oneWallet],
['with multiple wallets', () => twoWallets],
]
it('with no signers and empty addresses supplied', async () => {
const bw = await buildBoundWitness([])
expect(addressesContainsAll(bw, [])).toBeTrue()
})
describe.each(cases)('%s', (_, wallets) => {
let addresses: Address[]
beforeAll(() => {
addresses = wallets().map(x => x.address)
})
it('with all wallets as signers and empty addresses supplied', async () => {
const bw = await buildBoundWitness(wallets())
expect(addressesContainsAll(bw, [])).toBeTrue()
})
it('with all wallets as signers and all wallet addresses supplied', async () => {
const bw = await buildBoundWitness(wallets())
expect(addressesContainsAll(bw, addresses)).toBeTrue()
})
it('with all wallets (and extra wallets) as signers and all wallet addresses supplied', async () => {
const extraSigners = [...wallets(), await HDWallet.random()]
const bw = await buildBoundWitness(extraSigners)
expect(addressesContainsAll(bw, addresses)).toBeTrue()
})
})
})
describe('returns false', () => {
const cases: [string, () => WalletInstance[]][] = [
['with single wallet', () => oneWallet],
['with multiple wallets', () => twoWallets],
]
describe.each(cases)('%s', (_, wallets) => {
let addresses: Address[]
beforeAll(() => {
addresses = wallets().map(x => x.address)
})
it('with no signers and all wallet addresses supplied', async () => {
const [bw] = await new BoundWitnessBuilder().payload(payload).build()
expect(addressesContainsAll(bw, addresses)).toBeFalse()
})
it('with all signers except one and all wallet addresses supplied', async () => {
const lessSigners = [...wallets().slice(0, -1), await HDWallet.random()]
const bw = await buildBoundWitness(lessSigners)
expect(addressesContainsAll(bw, addresses)).toBeFalse()
})
it('with all different signers and all wallet addresses supplied', async () => {
const differentSigners = [await HDWallet.random(), await HDWallet.random()]
const bw = await buildBoundWitness(differentSigners)
expect(addressesContainsAll(bw, addresses)).toBeFalse()
})
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import type { Address } from '@xylabs/hex'
import type { WalletInstance } from '@xyo-network/account'
import { HDWallet } from '@xyo-network/account'
import { BoundWitnessBuilder } from '@xyo-network/boundwitness-builder'

import { addressesContainsAny } from '../addressesContainsAny.ts'

describe('addressesContainsAny', () => {
const payload = { schema: 'network.xyo.test', value: Date.now() }
let oneWallet: WalletInstance[] = []
let twoWallets: WalletInstance[] = []
beforeAll(async () => {
oneWallet = [await HDWallet.random()]
twoWallets = [await HDWallet.random(), await HDWallet.random()]
})
const buildBoundWitness = async (signers: WalletInstance[]) => {
const [bw] = await new BoundWitnessBuilder().signers(signers).payload(payload).build()
return bw
}
describe('returns true', () => {
const cases: [string, () => WalletInstance[]][] = [
['with no wallets', () => []],
['with single wallet', () => oneWallet],
['with multiple wallets', () => twoWallets],
]
it('with no signers and empty addresses supplied', async () => {
const bw = await buildBoundWitness([])
expect(addressesContainsAny(bw, [])).toBeTrue() // No signers and no addresses should return true
})
describe.each(cases)('%s', (_, wallets) => {
let addresses: Address[]
beforeAll(() => {
addresses = wallets().map(x => x.address)
})
it('with all wallets as signers and all wallet addresses supplied', async () => {
const bw = await buildBoundWitness(wallets())
expect(addressesContainsAny(bw, addresses)).toBeTrue() // Should be true if wallets exist
})
it('with all wallets (and extra wallets) as signers and all wallet addresses supplied', async () => {
const extraSigners = [...wallets(), await HDWallet.random()]
const bw = await buildBoundWitness(extraSigners)
expect(addressesContainsAny(bw, addresses)).toBeTrue() // Should still be true with extras
})
it('with only one matching signer', async () => {
const extraSigners = [await HDWallet.random(), ...wallets()]
const bw = await buildBoundWitness(extraSigners)
expect(addressesContainsAny(bw, addresses)).toBeTrue() // Should return true with one match
})
})
})
describe('returns false', () => {
const cases: [string, () => WalletInstance[]][] = [
// ['with no wallets', () => []],
['with single wallet', () => oneWallet],
['with multiple wallets', () => twoWallets],
]
describe.each(cases)('%s', (_, wallets) => {
let addresses: Address[]
beforeAll(() => {
addresses = wallets().map(x => x.address)
})
it('with no signers and all wallet addresses supplied', async () => {
const [bw] = await new BoundWitnessBuilder().payload(payload).build()
expect(addressesContainsAny(bw, addresses)).toBeFalse() // No signers, no match
})
it('with signers that do not include any of the wallet addresses supplied', async () => {
const differentSigners = [await HDWallet.random(), await HDWallet.random()]
const bw = await buildBoundWitness(differentSigners)
expect(addressesContainsAny(bw, addresses)).toBeFalse() // None of the wallet addresses are in the bound witness
})
it('with extra signers and no wallet addresses supplied', async () => {
const extraSigners = [await HDWallet.random(), await HDWallet.random()]
const bw = await buildBoundWitness(extraSigners)
expect(addressesContainsAny(bw, addresses)).toBeFalse() // None of the supplied addresses match
})
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,

},
"extends": "@xylabs/tsconfig-jest"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './addresses/index.ts'
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { Payload } from '@xyo-network/payload'
import { PayloadBuilder } from '@xyo-network/payload'
import { SchemaNameValidator } from '@xyo-network/schema-name-validator'

import { BoundWitnessValidator } from '../Validator'
import { BoundWitnessValidator } from '../Validator.ts'

const dumpErrors = (errors: Error[]) => {
for (const error of errors) {
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3745,6 +3745,13 @@ __metadata:
languageName: node
linkType: hard

"@xylabs/hex@npm:^4.0.10":
version: 4.0.10
resolution: "@xylabs/hex@npm:4.0.10"
checksum: 10/cad87986ced0e46e66c305d88dfd753772bd99701fe3b1fdbe97dee4d3ad05f7505dabbb1f5db9506c90caa69eeb8984b1031ebb5205c40839beb269982a5e73
languageName: node
linkType: hard

"@xylabs/hex@npm:^4.0.9":
version: 4.0.9
resolution: "@xylabs/hex@npm:4.0.9"
Expand Down Expand Up @@ -4414,6 +4421,7 @@ __metadata:
resolution: "@xyo-network/boundwitness-validator@workspace:packages/protocol/packages/boundwitness/packages/validator"
dependencies:
"@xylabs/arraybuffer": "npm:^4.0.9"
"@xylabs/hex": "npm:^4.0.10"
"@xylabs/lodash": "npm:^4.0.9"
"@xylabs/ts-scripts-yarn3": "npm:^4.0.7"
"@xylabs/tsconfig": "npm:^4.0.7"
Expand Down

0 comments on commit c626847

Please sign in to comment.