IPFS compatible text input for alliance CID (#7928)
* IPFS compatible text input for alliance CID * Adjust detect
This commit is contained in:
parent
8a47543e03
commit
4e90ec9663
@ -13,7 +13,6 @@
|
||||
"type": "module",
|
||||
"version": "0.118.2-22-x",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.18.9",
|
||||
"multiformats": "^9.7.1"
|
||||
"@babel/runtime": "^7.18.9"
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
import { Metadata, TypeRegistry } from '@polkadot/types';
|
||||
import substrate from '@polkadot/types-support/metadata/static-substrate';
|
||||
|
||||
import { createIpfsHash, createPalletCid } from './util';
|
||||
import { createCid, createPalletCid } from './util';
|
||||
|
||||
const registry = new TypeRegistry();
|
||||
const metadata = new Metadata(registry, substrate);
|
||||
@ -29,17 +29,17 @@ describe('util', (): void => {
|
||||
|
||||
describe('createIpfsHash', (): void => {
|
||||
it('encodes a pallet CID into an ipfs hash', (): void => {
|
||||
const cid = registry.createType('PalletAllianceCid', {
|
||||
codec: 0x70,
|
||||
hash_: {
|
||||
code: 0x12,
|
||||
digest: '0x5360ecbd380c10f43bc0a6aba27556580011a5e833592df8dcf330c94759e862'
|
||||
},
|
||||
version: 'V0'
|
||||
});
|
||||
|
||||
expect(
|
||||
createIpfsHash(
|
||||
registry.createType('PalletAllianceCid', {
|
||||
codec: 0x70,
|
||||
hash_: {
|
||||
code: 0x12,
|
||||
digest: '0x5360ecbd380c10f43bc0a6aba27556580011a5e833592df8dcf330c94759e862'
|
||||
},
|
||||
version: 'V0'
|
||||
})
|
||||
)
|
||||
createCid(cid).ipfs
|
||||
).toEqual('QmTx8GZrQGwQ1ZLquZ4yPqSukDdkvKwpYCULsfLo6G47TX');
|
||||
});
|
||||
});
|
||||
|
||||
@ -5,58 +5,18 @@ import type { PalletAllianceCid } from '@polkadot/types/lookup';
|
||||
import type { Registry } from '@polkadot/types/types';
|
||||
import type { Cid } from './types';
|
||||
|
||||
import { CID, digest, varint } from 'multiformats';
|
||||
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
|
||||
export function createIpfsHash (cid: PalletAllianceCid): string | null {
|
||||
try {
|
||||
const { codec, hash_: { code, digest: _bytes }, version } = cid;
|
||||
|
||||
// Since we use parse, encode into a fully-specified bytes to
|
||||
// pass - <varint code> + <varint length> + bytes
|
||||
const bytes = _bytes.toU8a(true);
|
||||
const codeLen = varint.encodingLength(code.toNumber());
|
||||
const sizeLen = varint.encodingLength(bytes.length);
|
||||
const encoded = new Uint8Array(codeLen + sizeLen + bytes.length);
|
||||
|
||||
varint.encodeTo(code.toNumber(), encoded, 0);
|
||||
varint.encodeTo(bytes.length, encoded, codeLen);
|
||||
encoded.set(bytes, codeLen + sizeLen);
|
||||
|
||||
return CID
|
||||
.create(version.index as 0, codec.toNumber(), digest.decode(encoded))
|
||||
.toString();
|
||||
} catch (error) {
|
||||
console.error(`createIpfs: ${(error as Error).message}::`, cid.toHuman());
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
import { fromIpfsCid, toIpfsCid } from '@polkadot/react-params/util';
|
||||
|
||||
export function createPalletCid (registry: Registry, cid: string): PalletAllianceCid | null {
|
||||
try {
|
||||
const { code: codec, multihash: { code, digest }, version } = CID.parse(cid);
|
||||
const expanded = fromIpfsCid(cid);
|
||||
|
||||
return registry.createType('PalletAllianceCid', {
|
||||
codec,
|
||||
hash: {
|
||||
code,
|
||||
digest: u8aToHex(digest)
|
||||
},
|
||||
version
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`encodeCid: ${(error as Error).message}::`, cid);
|
||||
|
||||
return null;
|
||||
}
|
||||
return expanded && registry.createType('PalletAllianceCid', expanded);
|
||||
}
|
||||
|
||||
export function createCid (cid: PalletAllianceCid): Cid {
|
||||
return {
|
||||
cid,
|
||||
ipfs: createIpfsHash(cid),
|
||||
ipfs: toIpfsCid(cid),
|
||||
key: cid.toHex()
|
||||
};
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
"version": "0.118.2-22-x",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.18.9",
|
||||
"@polkadot/react-components": "^0.118.2-22-x"
|
||||
"@polkadot/react-components": "^0.118.2-22-x",
|
||||
"multiformats": "^9.7.1"
|
||||
}
|
||||
}
|
||||
|
||||
54
packages/react-params/src/Param/Cid.tsx
Normal file
54
packages/react-params/src/Param/Cid.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2017-2022 @polkadot/react-params authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Props } from '../types';
|
||||
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import { Input } from '@polkadot/react-components';
|
||||
import { isCodec } from '@polkadot/util';
|
||||
|
||||
import { fromIpfsCid } from '../util';
|
||||
import Bare from './Bare';
|
||||
import Struct from './Struct';
|
||||
|
||||
function Cid (props: Props): React.ReactElement<Props> {
|
||||
const { className = '', defaultValue, isDisabled, isError, label, onChange, withLabel } = props;
|
||||
const [isValid, setIsValid] = useState(false);
|
||||
const [isStruct] = useState<boolean>(() => isDisabled || !defaultValue || isCodec(defaultValue.value));
|
||||
|
||||
const _onChange = useCallback(
|
||||
(_value: string): void => {
|
||||
const value = fromIpfsCid(_value);
|
||||
const isValid = !!value;
|
||||
|
||||
onChange && onChange({
|
||||
isValid,
|
||||
value
|
||||
});
|
||||
setIsValid(isValid);
|
||||
},
|
||||
[onChange]
|
||||
);
|
||||
|
||||
if (isStruct) {
|
||||
return <Struct {...props} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Bare className={className}>
|
||||
<Input
|
||||
className='full'
|
||||
isDisabled={isDisabled}
|
||||
isError={isError || !isValid}
|
||||
label={label}
|
||||
onChange={_onChange}
|
||||
placeholder='IPFS compatible CID'
|
||||
type='text'
|
||||
withLabel={withLabel}
|
||||
/>
|
||||
</Bare>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Cid);
|
||||
@ -14,6 +14,7 @@ import Balance from './Balance';
|
||||
import Bool from './Bool';
|
||||
import Bytes from './Bytes';
|
||||
import Call from './Call';
|
||||
import Cid from './Cid';
|
||||
import Code from './Code';
|
||||
import DispatchError from './DispatchError';
|
||||
import DispatchResult from './DispatchResult';
|
||||
@ -53,6 +54,7 @@ const componentDef: TypeToComponent[] = [
|
||||
{ c: Bool, t: ['bool'] },
|
||||
{ c: Bytes, t: ['Bytes', 'Vec<u8>'] },
|
||||
{ c: Call, t: ['Call', 'Proposal'] },
|
||||
{ c: Cid, t: ['PalletAllianceCid'] },
|
||||
{ c: Code, t: ['Code'] },
|
||||
{ c: DispatchError, t: DISPATCH_ERROR },
|
||||
{ c: DispatchResult, t: ['DispatchResult', 'Result<Null, SpRuntimeDispatchError>'] },
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Registry, TypeDef } from '@polkadot/types/types';
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
// FIXME Ideally, we want these as Base from api-codec - as a stop-gap, any this until we have
|
||||
// params returning types extending Base (i.e. anything from api-codec)
|
||||
@ -56,3 +57,12 @@ export interface ParamDef {
|
||||
name?: string;
|
||||
type: TypeDef;
|
||||
}
|
||||
|
||||
export interface ExpandedCid {
|
||||
codec: number;
|
||||
hash: {
|
||||
code: number;
|
||||
digest: HexString;
|
||||
};
|
||||
version: 0 | 1;
|
||||
}
|
||||
|
||||
53
packages/react-params/src/util.ts
Normal file
53
packages/react-params/src/util.ts
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2017-2022 @polkadot/react-params authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { PalletAllianceCid } from '@polkadot/types/lookup';
|
||||
import type { ExpandedCid } from './types';
|
||||
|
||||
import { CID, digest, varint } from 'multiformats';
|
||||
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
|
||||
export function fromIpfsCid (cid: string): ExpandedCid | null {
|
||||
try {
|
||||
const { code: codec, multihash: { code, digest }, version } = CID.parse(cid);
|
||||
|
||||
return {
|
||||
codec,
|
||||
hash: {
|
||||
code,
|
||||
digest: u8aToHex(digest)
|
||||
},
|
||||
version
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`fromIpfsCid: ${(error as Error).message}::`, cid);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function toIpfsCid (cid: PalletAllianceCid): string | null {
|
||||
try {
|
||||
const { codec, hash_: { code, digest: _bytes }, version } = cid;
|
||||
|
||||
// Since we use parse, encode into a fully-specified bytes to
|
||||
// pass - <varint code> + <varint length> + bytes
|
||||
const bytes = _bytes.toU8a(true);
|
||||
const codeLen = varint.encodingLength(code.toNumber());
|
||||
const sizeLen = varint.encodingLength(bytes.length);
|
||||
const encoded = new Uint8Array(codeLen + sizeLen + bytes.length);
|
||||
|
||||
varint.encodeTo(code.toNumber(), encoded, 0);
|
||||
varint.encodeTo(bytes.length, encoded, codeLen);
|
||||
encoded.set(bytes, codeLen + sizeLen);
|
||||
|
||||
return CID
|
||||
.create(version.index as 0, codec.toNumber(), digest.decode(encoded))
|
||||
.toString();
|
||||
} catch (error) {
|
||||
console.error(`toIpfsCid: ${(error as Error).message}::`, cid.toHuman());
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -2766,7 +2766,6 @@ __metadata:
|
||||
resolution: "@polkadot/app-alliance@workspace:packages/page-alliance"
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.18.9
|
||||
multiformats: ^9.7.1
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@ -3467,6 +3466,7 @@ __metadata:
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.18.9
|
||||
"@polkadot/react-components": ^0.118.2-22-x
|
||||
multiformats: ^9.7.1
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user