From 8b9e255fd2b88a09eda4bb74345f5e51a40cf7a8 Mon Sep 17 00:00:00 2001 From: Trubnikov Sergey Date: Fri, 16 Sep 2022 14:38:38 +0000 Subject: [PATCH] feat: Add `collection_admins` method to eth collection. --- --- a/tests/src/eth/collectionAdmin.test.ts +++ b/tests/src/eth/collectionAdmin.test.ts @@ -14,7 +14,8 @@ // along with Unique Network. If not, see . import {IKeyringPair} from '@polkadot/types/types'; -import {usingEthPlaygrounds, itEth, expect, EthUniqueHelper} from './util'; +import {IEthCrossAccountId} from '../util/playgrounds/types'; +import {usingEthPlaygrounds, itEth, expect, EthUniqueHelper} from './util/playgrounds'; async function recordEthFee(helper: EthUniqueHelper, userAddress: string, call: () => Promise) { const before = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress)); @@ -93,25 +94,25 @@ await collectionEvm.methods.addCollectionAdmin(newAdmin).send(); expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true; }); - - // itEth.skip('Check adminlist', async ({helper, privateKey}) => { - // const owner = await helper.eth.createAccountWithBalance(donor); + + itEth('Check adminlist', async ({helper, privateKey}) => { + const owner = await helper.eth.createAccountWithBalance(donor); - // const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C'); - // const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - // const admin1 = helper.eth.createAccount(); - // const admin2 = await privateKey('admin'); - // await collectionEvm.methods.addCollectionAdmin(admin1).send(); - // await collectionEvm.methods.addCollectionAdminSubstrate(admin2.addressRaw).send(); + const admin1 = helper.eth.createAccount(); + const admin2 = privateKey('admin'); + await collectionEvm.methods.addCollectionAdmin(admin1).send(); + await collectionEvm.methods.addCollectionAdminSubstrate(admin2.addressRaw).send(); - // const adminListRpc = await helper.collection.getAdmins(collectionId); - // let adminListEth = await collectionEvm.methods.collectionAdmins().call(); - // adminListEth = adminListEth.map((element: IEthCrossAccountId) => { - // return helper.address.convertCrossAccountFromEthCrossAcoount(element); - // }); - // expect(adminListRpc).to.be.like(adminListEth); - // }); + const adminListRpc = await helper.collection.getAdmins(collectionId); + let adminListEth = await collectionEvm.methods.collectionAdmins().call(); + adminListEth = adminListEth.map((element: IEthCrossAccountId) => { + return helper.address.convertCrossAccountFromEthCrossAcoount(element); + }); + expect(adminListRpc).to.be.like(adminListEth); + }); itEth('(!negative tests!) Add admin by ADMIN is not allowed', async ({helper}) => { const owner = await helper.eth.createAccountWithBalance(donor); --- a/tests/src/util/playgrounds/unique.ts +++ b/tests/src/util/playgrounds/unique.ts @@ -7,8 +7,10 @@ import {ApiPromise, WsProvider, Keyring} from '@polkadot/api'; import {ApiInterfaceEvents, SignerOptions} from '@polkadot/api/types'; -import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm} from '@polkadot/util-crypto'; +import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm, base58Encode, blake2AsU8a} from '@polkadot/util-crypto'; import {IKeyringPair} from '@polkadot/types/types'; +import {hexToU8a} from '@polkadot/util/hex'; +import {u8aConcat} from '@polkadot/util/u8a'; import { IApiListeners, IBlock, @@ -2368,6 +2370,73 @@ return CrossAccountId.translateSubToEth(subAddress); } + /** + * Encode key to substrate address + * @param key key for encoding address + * @param ss58Format prefix for encoding to the address of the corresponding network + * @returns encoded substrate address + */ + encodeSubstrateAddress (key: Uint8Array | string | bigint, ss58Format = 42): string { + const u8a :Uint8Array = typeof key === 'string' + ? hexToU8a(key) + : typeof key === 'bigint' + ? hexToU8a(key.toString(16)) + : key; + + if (ss58Format < 0 || ss58Format > 16383 || [46, 47].includes(ss58Format)) { + throw new Error(`ss58Format is not valid, received ${typeof ss58Format} "${ss58Format}"`); + } + + const allowedDecodedLengths = [1, 2, 4, 8, 32, 33]; + if (!allowedDecodedLengths.includes(u8a.length)) { + throw new Error(`key length is not valid, received ${u8a.length}, valid values are ${allowedDecodedLengths.join(', ')}`); + } + + const u8aPrefix = ss58Format < 64 + ? new Uint8Array([ss58Format]) + : new Uint8Array([ + ((ss58Format & 0xfc) >> 2) | 0x40, + (ss58Format >> 8) | ((ss58Format & 0x03) << 6), + ]); + + const input = u8aConcat(u8aPrefix, u8a); + + return base58Encode(u8aConcat( + input, + blake2AsU8a(input).subarray(0, [32, 33].includes(u8a.length) ? 2 : 1), + )); + } + + /** + * Restore substrate address from bigint representation + * @param number decimal representation of substrate address + * @returns substrate address + */ + restoreCrossAccountFromBigInt(number: bigint): TSubstrateAccount { + if (this.helper.api === null) { + throw 'Not connected'; + } + const res = this.helper.api.registry.createType('AccountId', '0x' + number.toString(16).padStart(64, '0')).toJSON(); + if (res === undefined || res === null) { + throw 'Restore address error'; + } + return res.toString(); + } + + /** + * Convert etherium cross account id to substrate cross account id + * @param ethCrossAccount etherium cross account + * @returns substrate cross account id + */ + convertCrossAccountFromEthCrossAcoount(ethCrossAccount: IEthCrossAccountId): ICrossAccountId { + if (ethCrossAccount.field_1 === '0') { + return {Ethereum: ethCrossAccount.field_0.toLocaleLowerCase()}; + } + + const ss58 = this.restoreCrossAccountFromBigInt(BigInt(ethCrossAccount.field_1)); + return {Substrate: ss58}; + } + paraSiblingSovereignAccount(paraid: number) { // We are getting a *sibling* parachain sovereign account, // so we need a sibling prefix: encoded(b"sibl") == 0x7369626c -- gitstuff