Skip to content

Commit

Permalink
fix: Make sure vscode is setup correctly for biome, fix decode/encode…
Browse files Browse the repository at this point in the history
…Permissions and add tests.
  • Loading branch information
richtera committed Apr 5, 2024
1 parent d10f47c commit e458a05
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 235 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ node_modules
/build
/docs/build
docs/html
.vscode/*
.nyc_output
coverage
*.tgz
Expand Down
27 changes: 27 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Test debugging",
"request": "launch",
"runtimeArgs": ["run-script", "test"],
"runtimeExecutable": "npm",
"skipFiles": ["<node_internals>/**"],
"type": "node"
},
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/examples/src/fetchData.js",
"outFiles": ["${workspaceFolder}/**/*.js"],
"env": {
"GLOBAL_AGENT_HTTP_PROXY": "http://127.0.0.1:9090"
}
}
]
}
17 changes: 17 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.defaultFormatter": "biomejs.biome",
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"typescript.format.enable": false,
"javascript.format.enable": false,
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
},
"[vue]": {
"editor.defaultFormatter": "biomejs.biome"
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"build:main": "tsc -p tsconfig.json",
"build:module": "tsc -p tsconfig.module.json",
"test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' nyc --reporter=text --reporter=lcov mocha",
"test:debug": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha --verbose",
"lint": "biome check .",
"lint:fix": "biome check . --apply",
"release": "standard-version"
Expand Down
76 changes: 48 additions & 28 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ import { hexToNumber, leftPad, numberToHex } from 'web3-utils'
// examples of schemas to load (for testing)
import { LSP1Schema, LSP3Schema, LSP6Schema, LSP12Schema } from './schemas'

import ERC725 from '.'
import ERC725, {
checkPermissions,
decodePermissions,
encodeKeyName,
encodePermissions,
supportsInterface
} from '.'
import { EthereumProvider, HttpProvider } from '../test/mockProviders'
import { mockSchema } from '../test/mockSchema'
import {
Expand Down Expand Up @@ -1400,7 +1406,7 @@ describe('Running @erc725/erc725.js tests...', () => {
const testCase = testCases[i]
it(`Encodes ${testCase.hex} permission correctly`, () => {
assert.deepStrictEqual(
ERC725.encodePermissions(testCase.permissions),
encodePermissions(testCase.permissions),
testCase.hex
)
assert.deepStrictEqual(
Expand All @@ -1412,7 +1418,7 @@ describe('Running @erc725/erc725.js tests...', () => {

it('Defaults permissions to false if not passed', () => {
assert.deepStrictEqual(
ERC725.encodePermissions({
encodePermissions({
EDITPERMISSIONS: true,
SETDATA: true
}),
Expand Down Expand Up @@ -1485,7 +1491,7 @@ describe('Running @erc725/erc725.js tests...', () => {
for (let i = 0; i < numberOfTests; i++) {
it(`Randomized test #${i + 1}`, () => {
const randomPermissions = generateRandomPermissions()
const encoded = ERC725.encodePermissions(randomPermissions)
const encoded = encodePermissions(randomPermissions)
const expectedHex = calculateExpectedHex(randomPermissions)
assert.strictEqual(
encoded,
Expand All @@ -1499,7 +1505,7 @@ describe('Running @erc725/erc725.js tests...', () => {
describe('all permissions', () => {
it('should encode ALL_PERMISSIONS correctly', () => {
const permissions = { ALL_PERMISSIONS: true }
const encoded = ERC725.encodePermissions(permissions)
const encoded = encodePermissions(permissions)

assert.strictEqual(
encoded,
Expand All @@ -1508,12 +1514,30 @@ describe('Running @erc725/erc725.js tests...', () => {
)
})

it('should not decode ALL_PERMISSIONS', () => {
it('should decode ALL_PERMISSIONS', () => {
const permissions = { ALL_PERMISSIONS: true }
const encoded = ERC725.encodePermissions(permissions)
const encoded = encodePermissions(permissions)

const decodedPermissions = ERC725.decodePermissions(encoded)
const decodedPermissions = decodePermissions(encoded)

assert.strictEqual(
decodedPermissions.ALL_PERMISSIONS,
true,
'Decoded permissions includes ALL_PERMISSIONS'
)
})

it('should not decode CALL or ALL_PERMISSIONS if perms are missing', () => {
const permissions = { ALL_PERMISSIONS: true, CALL: false }
const encoded = encodePermissions(permissions)

const decodedPermissions = decodePermissions(encoded)

assert.strictEqual(
decodedPermissions.CALL,
false,
'Decoded permissions includes CALL'
)
assert.strictEqual(
decodedPermissions.ALL_PERMISSIONS,
false,
Expand All @@ -1523,13 +1547,12 @@ describe('Running @erc725/erc725.js tests...', () => {

it('should allow editing of permissions', () => {
const permissions = { ALL_PERMISSIONS: true }
const encoded = ERC725.encodePermissions(permissions)
const encoded = encodePermissions(permissions)

const decodedPermissions = ERC725.decodePermissions(encoded)
const decodedPermissions = decodePermissions(encoded)
decodedPermissions.CALL = false
const reencodePermissions = ERC725.encodePermissions(decodedPermissions)
const redecodedPermissions =
ERC725.decodePermissions(reencodePermissions)
const reencodePermissions = encodePermissions(decodedPermissions)
const redecodedPermissions = decodePermissions(reencodePermissions)

assert.strictEqual(
redecodedPermissions.CALL,
Expand All @@ -1543,7 +1566,7 @@ describe('Running @erc725/erc725.js tests...', () => {
ALL_PERMISSIONS: true,
CHANGEOWNER: true
}
const encoded = ERC725.encodePermissions(permissions)
const encoded = encodePermissions(permissions)
assert.strictEqual(
encoded,
LSP6_DEFAULT_PERMISSIONS.ALL_PERMISSIONS,
Expand All @@ -1556,8 +1579,8 @@ describe('Running @erc725/erc725.js tests...', () => {
CHANGEOWNER: false // Explicitly disable CHANGEOWNER
}

const encoded = ERC725.encodePermissions(permissions)
const decodedPermissions = ERC725.decodePermissions(encoded)
const encoded = encodePermissions(permissions)
const decodedPermissions = decodePermissions(encoded)

// check that the permission is disabled
assert.strictEqual(
Expand All @@ -1573,7 +1596,7 @@ describe('Running @erc725/erc725.js tests...', () => {
const testCase = testCases[i]
it(`Decodes ${testCase.hex} permission correctly`, () => {
assert.deepStrictEqual(
ERC725.decodePermissions(testCase.hex),
decodePermissions(testCase.hex),
testCase.permissions
)

Expand All @@ -1585,7 +1608,7 @@ describe('Running @erc725/erc725.js tests...', () => {
}
it('Decodes 0xfff...fff admin permission correctly', () => {
assert.deepStrictEqual(
ERC725.decodePermissions(
decodePermissions(
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
),
{
Expand Down Expand Up @@ -1691,7 +1714,7 @@ describe('encodeKeyName', () => {

it('is available on instance and class', () => {
assert.deepStrictEqual(
ERC725.encodeKeyName('MyKeyName'),
encodeKeyName('MyKeyName'),
'0x35e6950bc8d21a1699e58328a3c4066df5803bb0b570d0150cb3819288e764b2'
)
assert.deepStrictEqual(
Expand All @@ -1702,7 +1725,7 @@ describe('encodeKeyName', () => {

it('works for dynamic keys', () => {
assert.deepStrictEqual(
ERC725.encodeKeyName(
encodeKeyName(
'FavouriteFood:<address>',
'0xa4FBbFe353124E6fa6Bb7f8e088a9269dF552EA2'
),
Expand All @@ -1722,7 +1745,7 @@ describe('supportsInterface', () => {
const erc725Instance = new ERC725([])

it('is available on instance and class', () => {
assert.typeOf(ERC725.supportsInterface, 'function')
assert.typeOf(supportsInterface, 'function')
assert.typeOf(erc725Instance.supportsInterface, 'function')
})

Expand All @@ -1732,7 +1755,7 @@ describe('supportsInterface', () => {

it('should throw when provided address is not an address', async () => {
try {
await ERC725.supportsInterface(interfaceId, {
await supportsInterface(interfaceId, {
address: 'notAnAddress',
rpcUrl
})
Expand All @@ -1743,7 +1766,7 @@ describe('supportsInterface', () => {

it('should throw when rpcUrl is not provided on non instantiated class', async () => {
try {
await ERC725.supportsInterface(interfaceId, {
await supportsInterface(interfaceId, {
address: contractAddress,
// @ts-ignore
rpcUrl: undefined
Expand Down Expand Up @@ -1777,7 +1800,7 @@ describe('checkPermissions', () => {
})

it('is available on class', () => {
assert.typeOf(ERC725.checkPermissions, 'function')
assert.typeOf(checkPermissions, 'function')

const requiredPermissions = [
'0x0000000000000000000000000000000000000000000000000000000000000004',
Expand All @@ -1786,10 +1809,7 @@ describe('checkPermissions', () => {
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000ff51'

const result = ERC725.checkPermissions(
requiredPermissions,
grantedPermissions
)
const result = checkPermissions(requiredPermissions, grantedPermissions)

assert.equal(result, false)
})
Expand Down
87 changes: 54 additions & 33 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import { encodeKeyName, isDynamicKeyName } from './lib/encodeKeyName'

import { decodeData } from './lib/decodeData'
import { decodeMappingKey } from './lib/decodeMappingKey'
import { checkPermissions, supportsInterface } from './lib/detector'
import { _supportsInterface, checkPermissions } from './lib/detector'
import { decodeValueType, encodeValueType } from './lib/encoder'
import { getData } from './lib/getData'
import { getDataFromExternalSources } from './lib/getDataFromExternalSources'
Expand All @@ -67,7 +67,8 @@ export {
ERC725JSONSchema,
ERC725JSONSchemaKeyType,
ERC725JSONSchemaValueContent,
ERC725JSONSchemaValueType
ERC725JSONSchemaValueType,
Permissions
}

export { ERC725Config, KeyValuePair, ProviderTypes } from './types'
Expand All @@ -82,7 +83,54 @@ export {
} from './lib/encoder'
export { getDataFromExternalSources } from './lib/getDataFromExternalSources'
export { encodePermissions, decodePermissions } from './lib/permissions'
export { supportsInterface, checkPermissions } from './lib/detector'
export { checkPermissions } from './lib/detector'

// PRIVATE FUNCTION
function initializeProvider(providerOrRpcUrl, gasInfo) {
// do not fail on no-provider
if (!providerOrRpcUrl) return undefined

// if provider is a string, assume it's a rpcUrl
if (typeof providerOrRpcUrl === 'string') {
return new ProviderWrapper(new HttpProvider(providerOrRpcUrl), gasInfo)
}

if (
typeof providerOrRpcUrl.request === 'function' ||
typeof providerOrRpcUrl.send === 'function'
)
return new ProviderWrapper(providerOrRpcUrl, gasInfo)

throw new Error(`Incorrect or unsupported provider ${providerOrRpcUrl}`)
}

// PUBLIC FUNCTION
export async function supportsInterface(
interfaceIdOrName: string,
options: {
address: string
rpcUrl: string
gas?: number
provider?: ProviderWrapper
}
): Promise<boolean> {
if (!isAddress(options.address)) {
throw new Error('Invalid address')
}
if (!options.rpcUrl) {
throw new Error('Missing RPC URL')
}

return _supportsInterface(interfaceIdOrName, {
address: options.address,
provider:
options.provider ||
initializeProvider(
options.rpcUrl,
options?.gas ? options?.gas : DEFAULT_GAS_VALUE
)
})
}

/**
* This package is currently in early stages of development, <br/>use only for testing or experimentation purposes.<br/>
Expand Down Expand Up @@ -179,21 +227,7 @@ export class ERC725 {
}

private static initializeProvider(providerOrRpcUrl, gasInfo) {
// do not fail on no-provider
if (!providerOrRpcUrl) return undefined

// if provider is a string, assume it's a rpcUrl
if (typeof providerOrRpcUrl === 'string') {
return new ProviderWrapper(new HttpProvider(providerOrRpcUrl), gasInfo)
}

if (
typeof providerOrRpcUrl.request === 'function' ||
typeof providerOrRpcUrl.send === 'function'
)
return new ProviderWrapper(providerOrRpcUrl, gasInfo)

throw new Error(`Incorrect or unsupported provider ${providerOrRpcUrl}`)
return initializeProvider(providerOrRpcUrl, gasInfo)
}

private getAddressAndProvider() {
Expand Down Expand Up @@ -559,7 +593,7 @@ export class ERC725 {
async supportsInterface(interfaceIdOrName: string): Promise<boolean> {
const { address, provider } = this.getAddressAndProvider()

return supportsInterface(interfaceIdOrName, {
return _supportsInterface(interfaceIdOrName, {
address,
provider
})
Expand All @@ -577,20 +611,7 @@ export class ERC725 {
interfaceIdOrName: string,
options: { address: string; rpcUrl: string; gas?: number }
): Promise<boolean> {
if (!isAddress(options.address)) {
throw new Error('Invalid address')
}
if (!options.rpcUrl) {
throw new Error('Missing RPC URL')
}

return supportsInterface(interfaceIdOrName, {
address: options.address,
provider: ERC725.initializeProvider(
options.rpcUrl,
options?.gas ? options?.gas : DEFAULT_GAS_VALUE
)
})
return supportsInterface(interfaceIdOrName, options)
}

/**
Expand Down
Loading

0 comments on commit e458a05

Please sign in to comment.