mirror of
https://github.com/pezkuwichain/pezkuwi-apps.git
synced 2026-10-20 18:56:30 +00:00
Drop the foreign chains' parameters; fix the Zagros genesis
- api/constants: only PEZKUWI_GENESIS and ZAGROS_GENESIS remain. The Zagros value was a placeholder from before its launch; it is now the live chain's genesis (0x1b0b4727…2cd5, measured). - Inflation, proposal thresholds and governance tracks keep the Pezkuwi entries; the Dicle, Kulupu, Cere, Vara, Joystream, zkVerify, Dock, Neatcoin and NFTMart ones go, as do the dicle tracks. - getTeleportWeight was used nowhere: removed. - page-society: the Dicle-only "design samples" button and its canary drawing go, with their table column. - page-assets: the next-id rule keyed on Polkadot's and Kusama's asset hub genesis never matched a Pezkuwi chain; removed, no change there. - ParaLink: the Subscan link went to scan.pezkuwichain.io, which does not resolve; removed (coretime keeps the homepage link). - typesBundle generator: no unused sort-keys directive when empty.
This commit is contained in:
1 parent
66e8d6c1be
commit
8c9ee48278
16 files changed
+20
-655
No files matched your search
@@ -1,54 +1,8 @@
|
|||||||
// Copyright 2017-2026 @pezkuwi/apps-config authors & contributors
|
// Copyright 2017-2026 @pezkuwi/apps-config authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { HexString } from '@pezkuwi/util/types';
|
|
||||||
|
|
||||||
import { knownGenesis } from '@pezkuwi/networks/defaults';
|
|
||||||
import { assert, BN } from '@pezkuwi/util';
|
|
||||||
|
|
||||||
export function getGenesis (name: string): HexString {
|
|
||||||
const network = Object.entries(knownGenesis).find(([network]) => network === name);
|
|
||||||
|
|
||||||
assert(network?.[1][0], `Unable to find genesisHash for ${name}`);
|
|
||||||
|
|
||||||
return network[1][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const KULUPU_GENESIS = getGenesis('kulupu');
|
|
||||||
|
|
||||||
// Dicle - Pezkuwi canary relay chain (placeholder until mainnet launch)
|
|
||||||
export const DICLE_GENESIS = '0xd9d3cd7c1e5d890d969b957f4c5b71a111bbeeabc968f1d0d4538c2663f080a7';
|
|
||||||
|
|
||||||
// Pezkuwi - Pezkuwi main relay chain
|
// Pezkuwi - Pezkuwi main relay chain
|
||||||
export const PEZKUWI_GENESIS = '0x1aa94987791a5544e9667ec249d2cef1b8fdd6083c85b93fc37892d54a1156ca';
|
export const PEZKUWI_GENESIS = '0x1aa94987791a5544e9667ec249d2cef1b8fdd6083c85b93fc37892d54a1156ca';
|
||||||
export const PEZKUWI_DENOM_BLOCK = new BN(1248328);
|
|
||||||
|
|
||||||
export const PASEO_GENESIS = '0x77afd6190f1554ad45fd0d31aee62aacc33c6db0ea801129acb813f913e0764f';
|
// Zagros - Pezkuwi test relay chain
|
||||||
|
export const ZAGROS_GENESIS = '0x1b0b4727bbb5e44ed587d1056b4ad537ffb330034509a58866a088d77e792cd5';
|
||||||
// Zagros - Pezkuwi test relay chain (placeholder until testnet launch)
|
|
||||||
export const ZAGROS_GENESIS = '0x297f5a4d105b4b28312586ff1915572ffe4ee015ff772b76399ecbff25a22026';
|
|
||||||
|
|
||||||
// PezkuwiChain - Pezkuwi dev relay chain (placeholder until devnet launch)
|
|
||||||
export const PEZKUWICHAIN_GENESIS = '0x32154fd2c844f928c82964ff66168b41b15fc235f3a956d14393734c1ed4326b';
|
|
||||||
|
|
||||||
export const NEATCOIN_GENESIS = '0xfbb541421d30423c9a753ffa844b64fd44d823f513bf49e3b73b3a656309a595';
|
|
||||||
|
|
||||||
export const DOCK_GENESIS = '0x6bfe24dca2a3be10f22212678ac13a6446ec764103c0f3471c71609eac384aae';
|
|
||||||
|
|
||||||
export const DOCK_POS_TESTNET_GENESIS = '0x59d93e2ce42abb8aa52ca9a9e820233667104751f8f2980578a47a26a7235027';
|
|
||||||
|
|
||||||
export const NFTMART_GENESIS = '0xfcf9074303d8f319ad1bf0195b145871977e7c375883b834247cb01ff22f51f9';
|
|
||||||
|
|
||||||
export const CERE_NETWORK_GENESIS = '0x81443836a9a24caaa23f1241897d1235717535711d1d3fe24eae4fdc942c092c';
|
|
||||||
|
|
||||||
export const CERE_NETWORK_TESTNET_GENESIS = '0x42b9b44b4950b6c1edae543a7696caf8d0a160e9bc0424ab4ab217f7a8ba30dc';
|
|
||||||
|
|
||||||
export const VARA_NETWORK_GENESIS = '0xfe1b4c55fd4d668101126434206571a7838a8b6b93a6d1b95d607e78e6c53763';
|
|
||||||
|
|
||||||
export const VARA_NETWORK_TESTNET_GENESIS = '0x525639f713f397dcf839bd022cd821f367ebcf179de7b9253531f8adbe5436d6';
|
|
||||||
|
|
||||||
export const JOYSTREAM_GENESIS = '0x6b5e488e0fa8f9821110d5c13f4c468abcd43ce5e297e62b34c53c3346465956';
|
|
||||||
|
|
||||||
export const ZKVERIFY_GENESIS = '0x060e3dd3fa2904d031206bb913c954687a2bcc350e5a83d33d9e273ad21460f1';
|
|
||||||
|
|
||||||
export const ZKVERIFY_VOLTA_GENESIS = '0xff7fe5a610f15fe7a0c52f94f86313fb7db7d3786e7f8acf2b66c11d5be7c242';
|
|
||||||
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
export * from './inflation.js';
|
export * from './inflation.js';
|
||||||
export * from './proposalThresholds.js';
|
export * from './proposalThresholds.js';
|
||||||
export * from './teleport.js';
|
|
||||||
export * from './tracks/index.js';
|
export * from './tracks/index.js';
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import type { ApiPromise } from '@pezkuwi/api';
|
import type { ApiPromise } from '@pezkuwi/api';
|
||||||
|
|
||||||
import { CERE_NETWORK_GENESIS, CERE_NETWORK_TESTNET_GENESIS, DICLE_GENESIS, DOCK_POS_TESTNET_GENESIS, JOYSTREAM_GENESIS, NEATCOIN_GENESIS, NFTMART_GENESIS, PEZKUWI_GENESIS, VARA_NETWORK_GENESIS, VARA_NETWORK_TESTNET_GENESIS, ZKVERIFY_GENESIS, ZKVERIFY_VOLTA_GENESIS } from '../constants.js';
|
import { PEZKUWI_GENESIS } from '../constants.js';
|
||||||
|
|
||||||
interface InflationParams {
|
interface InflationParams {
|
||||||
auctionAdjust: number;
|
auctionAdjust: number;
|
||||||
@@ -27,33 +27,8 @@ const DEFAULT_PARAMS: InflationParams = {
|
|||||||
stakeTarget: 0.5
|
stakeTarget: 0.5
|
||||||
};
|
};
|
||||||
|
|
||||||
const CERE_NETWORK_INFLATION_PARAMS = { ...DEFAULT_PARAMS, maxInflation: 0.05, minInflation: 0.0001, stakeTarget: 0.2 };
|
|
||||||
|
|
||||||
const VARA_NETWORK_INFLATION_PARAMS = { ...DEFAULT_PARAMS, maxInflation: 0, minInflation: 0.0001, stakeTarget: 0.85 };
|
|
||||||
|
|
||||||
const JOYSTREAM_INFLATION_PARAMS = { ...DEFAULT_PARAMS, maxInflation: 0.03, minInflation: 0.0075 };
|
|
||||||
|
|
||||||
const ZKVERIFY_INFLATION_PARAMS = { ...DEFAULT_PARAMS, auctionAdjust: 0, maxInflation: 0.025, minInflation: 0.025, stakeTarget: 0 };
|
|
||||||
|
|
||||||
const ZKVERIFY_VOLTA_INFLATION_PARAMS = { ...DEFAULT_PARAMS, auctionAdjust: 0, maxInflation: 0.025, minInflation: 0.025, stakeTarget: 0 };
|
|
||||||
|
|
||||||
const KNOWN_PARAMS: Record<string, InflationParams> = {
|
const KNOWN_PARAMS: Record<string, InflationParams> = {
|
||||||
[CERE_NETWORK_GENESIS]: CERE_NETWORK_INFLATION_PARAMS,
|
[PEZKUWI_GENESIS]: { ...DEFAULT_PARAMS, stakeTarget: 0.75 }
|
||||||
[CERE_NETWORK_TESTNET_GENESIS]: CERE_NETWORK_INFLATION_PARAMS,
|
|
||||||
// 30% for up to 60 slots, see
|
|
||||||
// https://github.com/pezkuwichain/pezkuwi/blob/816cb64ea16102c6c79f6be2a917d832d98df757/runtime/dicle/src/lib.rs#L526-L527
|
|
||||||
// 75% ideal target, see
|
|
||||||
// https://github.com/pezkuwichain/pezkuwi/blob/816cb64ea16102c6c79f6be2a917d832d98df757/runtime/dicle/src/lib.rs#L529-L531
|
|
||||||
[DICLE_GENESIS]: { ...DEFAULT_PARAMS, auctionAdjust: (0.3 / 60), auctionMax: 60, stakeTarget: 0.75 },
|
|
||||||
[DOCK_POS_TESTNET_GENESIS]: { ...DEFAULT_PARAMS, stakeTarget: 0.75 },
|
|
||||||
[JOYSTREAM_GENESIS]: JOYSTREAM_INFLATION_PARAMS,
|
|
||||||
[NEATCOIN_GENESIS]: { ...DEFAULT_PARAMS, stakeTarget: 0.75 },
|
|
||||||
[NFTMART_GENESIS]: { ...DEFAULT_PARAMS, falloff: 0.04, stakeTarget: 0.60 },
|
|
||||||
[PEZKUWI_GENESIS]: { ...DEFAULT_PARAMS, stakeTarget: 0.75 },
|
|
||||||
[VARA_NETWORK_GENESIS]: VARA_NETWORK_INFLATION_PARAMS,
|
|
||||||
[VARA_NETWORK_TESTNET_GENESIS]: VARA_NETWORK_INFLATION_PARAMS,
|
|
||||||
[ZKVERIFY_GENESIS]: ZKVERIFY_INFLATION_PARAMS,
|
|
||||||
[ZKVERIFY_VOLTA_GENESIS]: ZKVERIFY_VOLTA_INFLATION_PARAMS
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getInflationParams (api: ApiPromise): InflationParams {
|
export function getInflationParams (api: ApiPromise): InflationParams {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import type { ApiPromise } from '@pezkuwi/api';
|
import type { ApiPromise } from '@pezkuwi/api';
|
||||||
|
|
||||||
import { DICLE_GENESIS, KULUPU_GENESIS, PEZKUWI_GENESIS } from '../constants.js';
|
import { PEZKUWI_GENESIS } from '../constants.js';
|
||||||
|
|
||||||
// normal fast-track proposals
|
// normal fast-track proposals
|
||||||
const FAST_TRACK: Record<string, number> = {
|
const FAST_TRACK: Record<string, number> = {
|
||||||
@@ -16,21 +16,16 @@ const FAST_TRACK_NO_DELAY: Record<string, number> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const PROPOSE: Record<string, number> = {
|
const PROPOSE: Record<string, number> = {
|
||||||
[DICLE_GENESIS]: 1 / 2,
|
|
||||||
[KULUPU_GENESIS]: 1,
|
|
||||||
[PEZKUWI_GENESIS]: 3 / 5,
|
[PEZKUWI_GENESIS]: 3 / 5,
|
||||||
default: 1 / 2
|
default: 1 / 2
|
||||||
};
|
};
|
||||||
|
|
||||||
const SLASH: Record<string, number> = {
|
const SLASH: Record<string, number> = {
|
||||||
[DICLE_GENESIS]: 1 / 2,
|
|
||||||
[PEZKUWI_GENESIS]: 3 / 4,
|
[PEZKUWI_GENESIS]: 3 / 4,
|
||||||
default: 1 / 2
|
default: 1 / 2
|
||||||
};
|
};
|
||||||
|
|
||||||
const TREASURY: Record<string, number> = {
|
const TREASURY: Record<string, number> = {
|
||||||
[DICLE_GENESIS]: 3 / 5,
|
|
||||||
[KULUPU_GENESIS]: 1 / 2,
|
|
||||||
[PEZKUWI_GENESIS]: 3 / 5,
|
[PEZKUWI_GENESIS]: 3 / 5,
|
||||||
default: 3 / 5
|
default: 3 / 5
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
// Copyright 2017-2026 @pezkuwi/apps-config authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import type { ApiPromise } from '@pezkuwi/api';
|
|
||||||
|
|
||||||
import { DICLE_GENESIS } from '../constants.js';
|
|
||||||
|
|
||||||
// 4 * BaseXcmWeight on Dicle
|
|
||||||
const DICLE_WEIGHT = 4 * 1_000_000_000;
|
|
||||||
|
|
||||||
const DEFAULT_WEIGHT = DICLE_WEIGHT;
|
|
||||||
|
|
||||||
const KNOWN_WEIGHTS: Record<string, number> = {
|
|
||||||
[DICLE_GENESIS]: DICLE_WEIGHT
|
|
||||||
};
|
|
||||||
|
|
||||||
export function getTeleportWeight (api: ApiPromise): number {
|
|
||||||
return KNOWN_WEIGHTS[api.genesisHash.toHex()] || DEFAULT_WEIGHT;
|
|
||||||
}
|
|
||||||
@@ -1,208 +0,0 @@
|
|||||||
// Copyright 2017-2026 @pezkuwi/apps-config authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import type { TrackInfo } from './types.js';
|
|
||||||
|
|
||||||
import { BN } from '@pezkuwi/util';
|
|
||||||
|
|
||||||
import { compareFellowshipRank, formatSpendFactory } from './util.js';
|
|
||||||
|
|
||||||
// hardcoded here since this is static (hopefully no re-denomination anytime...)
|
|
||||||
const formatSpend = formatSpendFactory({
|
|
||||||
decimals: 12,
|
|
||||||
forceUnit: '-',
|
|
||||||
withSi: true,
|
|
||||||
withUnit: 'DCL'
|
|
||||||
});
|
|
||||||
|
|
||||||
// https://github.com/pezkuwichain/pezkuwi/blob/6e3f2c5b4b6e6927915de2f784e1d831717760fa/runtime/dicle/constants/src/lib.rs#L28-L32
|
|
||||||
const UNITS = new BN(1_000_000_000_000);
|
|
||||||
const QUID = UNITS.divn(30);
|
|
||||||
const GRAND = QUID.muln(1_000);
|
|
||||||
|
|
||||||
// https://github.com/pezkuwichain/pezkuwi/blob/6e3f2c5b4b6e6927915de2f784e1d831717760fa/runtime/dicle/src/governance/origins.rs#L170-L179
|
|
||||||
const SPEND_LIMITS = {
|
|
||||||
BigSpender: formatSpend(1_000, GRAND),
|
|
||||||
BigTipper: formatSpend(1, GRAND),
|
|
||||||
MediumSpender: formatSpend(100, GRAND),
|
|
||||||
SmallSpender: formatSpend(10, GRAND),
|
|
||||||
SmallTipper: formatSpend(250, QUID),
|
|
||||||
Treasurer: formatSpend(10_000, GRAND)
|
|
||||||
};
|
|
||||||
|
|
||||||
export const dicle: Record<string, TrackInfo[]> = {
|
|
||||||
fellowshipReferenda: [
|
|
||||||
{
|
|
||||||
compare: compareFellowshipRank(0),
|
|
||||||
id: 0,
|
|
||||||
name: 'candidates',
|
|
||||||
origin: { Origins: 'FellowshipInitiates' },
|
|
||||||
text: 'Origin commanded by any members of the Pezkuwi Fellowship (no Dan grade needed)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
compare: compareFellowshipRank(1),
|
|
||||||
id: 1,
|
|
||||||
name: 'members',
|
|
||||||
origin: { Origins: 'Fellowship1Dan' },
|
|
||||||
text: 'Origin commanded by rank 1 of the Pezkuwi Fellowship and with a success of 1'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
compare: compareFellowshipRank(2),
|
|
||||||
id: 2,
|
|
||||||
name: 'proficients',
|
|
||||||
origin: { Origins: 'Fellowship2Dan' },
|
|
||||||
text: 'Origin commanded by rank 2 of the Pezkuwi Fellowship and with a success of 2'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
|
|
||||||
compare: compareFellowshipRank(3),
|
|
||||||
id: 3,
|
|
||||||
name: 'fellows',
|
|
||||||
origin: [
|
|
||||||
{ Origins: 'Fellowship3Dan' },
|
|
||||||
{ Origins: 'Fellows' }
|
|
||||||
],
|
|
||||||
text: 'Origin commanded by Pezkuwi Fellows (3rd Dan fellows or greater)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
compare: compareFellowshipRank(4),
|
|
||||||
id: 4,
|
|
||||||
name: 'senior fellows',
|
|
||||||
origin: { Origins: 'Fellowship4Dan' },
|
|
||||||
text: 'Origin commanded by rank 4 of the Pezkuwi Fellowship and with a success of 4'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
compare: compareFellowshipRank(5),
|
|
||||||
id: 5,
|
|
||||||
name: 'experts',
|
|
||||||
origin: [
|
|
||||||
{ Origins: 'Fellowship5Dan' },
|
|
||||||
{ Origins: 'FellowshipExperts' }
|
|
||||||
],
|
|
||||||
text: 'Origin commanded by Pezkuwi Experts (5th Dan fellows or greater)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
compare: compareFellowshipRank(6),
|
|
||||||
id: 6,
|
|
||||||
name: 'senior experts',
|
|
||||||
origin: { Origins: 'Fellowship6Dan' },
|
|
||||||
text: 'Origin commanded by rank 6 of the Pezkuwi Fellowship and with a success of 6'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
compare: compareFellowshipRank(7),
|
|
||||||
id: 7,
|
|
||||||
name: 'masters',
|
|
||||||
origin: [
|
|
||||||
{ Origins: 'Fellowship7Dan' },
|
|
||||||
{ Origins: 'FellowshipMasters' }
|
|
||||||
],
|
|
||||||
text: 'Origin commanded by Pezkuwi Masters (7th Dan fellows of greater)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
compare: compareFellowshipRank(8),
|
|
||||||
id: 8,
|
|
||||||
name: 'senior masters',
|
|
||||||
origin: { Origins: 'Fellowship8Dan' },
|
|
||||||
text: 'Origin commanded by rank 8 of the Pezkuwi Fellowship and with a success of 8'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
compare: compareFellowshipRank(9),
|
|
||||||
id: 9,
|
|
||||||
name: 'grand masters',
|
|
||||||
origin: { Origins: 'Fellowship9Dan' },
|
|
||||||
text: 'Origin commanded by rank 9 of the Pezkuwi Fellowship and with a success of 9'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
referenda: [
|
|
||||||
{
|
|
||||||
id: 0,
|
|
||||||
name: 'root',
|
|
||||||
origin: { system: 'Root' },
|
|
||||||
text: 'Origin for the system root'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: 'whitelisted_caller',
|
|
||||||
origin: { Origins: 'WhitelistedCaller' },
|
|
||||||
text: 'Origin able to dispatch a whitelisted call'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10,
|
|
||||||
name: 'staking_admin',
|
|
||||||
origin: { Origins: 'StakingAdmin' },
|
|
||||||
text: 'Origin for cancelling slashes'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 11,
|
|
||||||
name: 'treasurer',
|
|
||||||
origin: { Origins: 'Treasurer' },
|
|
||||||
text: 'Origin for spending (any amount of) funds'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 12,
|
|
||||||
name: 'lease_admin',
|
|
||||||
origin: { Origins: 'LeaseAdmin' },
|
|
||||||
text: 'Origin able to force slot leases'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 13,
|
|
||||||
name: 'fellowship_admin',
|
|
||||||
origin: { Origins: 'FellowshipAdmin' },
|
|
||||||
text: 'Origin for managing the composition of the fellowship'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 14,
|
|
||||||
name: 'general_admin',
|
|
||||||
origin: { Origins: 'GeneralAdmin' },
|
|
||||||
text: 'Origin for managing the registrar'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 15,
|
|
||||||
name: 'auction_admin',
|
|
||||||
origin: { Origins: 'AuctionAdmin' },
|
|
||||||
text: 'Origin for starting auctions'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 20,
|
|
||||||
name: 'referendum_canceller',
|
|
||||||
origin: { Origins: 'ReferendumCanceller' },
|
|
||||||
text: 'Origin able to cancel referenda'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 21,
|
|
||||||
name: 'referendum_killer',
|
|
||||||
origin: { Origins: 'ReferendumKiller' },
|
|
||||||
text: 'Origin able to kill referenda'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 30,
|
|
||||||
name: 'small_tipper',
|
|
||||||
origin: { Origins: 'SmallTipper' },
|
|
||||||
text: `Origin able to spend up to ${SPEND_LIMITS.SmallTipper} from the treasury at once`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 31,
|
|
||||||
name: 'big_tipper',
|
|
||||||
origin: { Origins: 'BigTipper' },
|
|
||||||
text: `Origin able to spend up to ${SPEND_LIMITS.BigTipper} from the treasury at once`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 32,
|
|
||||||
name: 'small_spender',
|
|
||||||
origin: { Origins: 'SmallSpender' },
|
|
||||||
text: `Origin able to spend up to ${SPEND_LIMITS.SmallSpender} from the treasury at once`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 33,
|
|
||||||
name: 'medium_spender',
|
|
||||||
origin: { Origins: 'MediumSpender' },
|
|
||||||
text: `Origin able to spend up to ${SPEND_LIMITS.MediumSpender} from the treasury at once`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 34,
|
|
||||||
name: 'big_spender',
|
|
||||||
origin: { Origins: 'BigSpender' },
|
|
||||||
text: `Origin able to spend up to ${SPEND_LIMITS.BigSpender} from the treasury at once`
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
@@ -4,17 +4,14 @@
|
|||||||
import type { ApiPromise } from '@pezkuwi/api';
|
import type { ApiPromise } from '@pezkuwi/api';
|
||||||
import type { TrackInfo } from './types.js';
|
import type { TrackInfo } from './types.js';
|
||||||
|
|
||||||
import { DICLE_GENESIS, PEZKUWI_GENESIS } from '../../constants.js';
|
import { PEZKUWI_GENESIS } from '../../constants.js';
|
||||||
import { dicle } from './dicle.js';
|
|
||||||
import { pezkuwi } from './pezkuwi.js';
|
import { pezkuwi } from './pezkuwi.js';
|
||||||
|
|
||||||
const KNOWN_GENE_TRACKS: Record<string, Record<string, TrackInfo[]>> = {
|
const KNOWN_GENE_TRACKS: Record<string, Record<string, TrackInfo[]>> = {
|
||||||
[DICLE_GENESIS]: dicle,
|
|
||||||
[PEZKUWI_GENESIS]: pezkuwi
|
[PEZKUWI_GENESIS]: pezkuwi
|
||||||
};
|
};
|
||||||
|
|
||||||
const KNOWN_SPEC_TRACKS: Record<string, Record<string, TrackInfo[]>> = {
|
const KNOWN_SPEC_TRACKS: Record<string, Record<string, TrackInfo[]>> = {
|
||||||
dicle,
|
|
||||||
// for kitchensink, we just use the root
|
// for kitchensink, we just use the root
|
||||||
node: {
|
node: {
|
||||||
referenda: [
|
referenda: [
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ describe('typesBundle', (): void => {
|
|||||||
const typesBundle: { chain: Record<string, unknown>, spec: Record<string, unknown> } = { chain: {}, spec: {} };
|
const typesBundle: { chain: Record<string, unknown>, spec: Record<string, unknown> } = { chain: {}, spec: {} };
|
||||||
|
|
||||||
afterAll((): void => {
|
afterAll((): void => {
|
||||||
|
// sort-keys has nothing to report (and its directive is flagged as unused) without entries
|
||||||
|
const isEmpty = !specEntries.length && !chainEntries.length;
|
||||||
|
const sortKeys = isEmpty
|
||||||
|
? ''
|
||||||
|
: '\n/* eslint-disable sort-keys */';
|
||||||
|
|
||||||
fs.writeFileSync('packages/apps-config/src/api/typesBundle.ts', `// Copyright 2017-2026 @pezkuwi/apps-config authors & contributors
|
fs.writeFileSync('packages/apps-config/src/api/typesBundle.ts', `// Copyright 2017-2026 @pezkuwi/apps-config authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
@@ -28,8 +34,7 @@ describe('typesBundle', (): void => {
|
|||||||
import type { OverrideBundleType } from '@pezkuwi/types/types';
|
import type { OverrideBundleType } from '@pezkuwi/types/types';
|
||||||
|
|
||||||
/* eslint-disable @stylistic/quotes */
|
/* eslint-disable @stylistic/quotes */
|
||||||
/* eslint-disable @stylistic/quote-props */
|
/* eslint-disable @stylistic/quote-props */${sortKeys}
|
||||||
/* eslint-disable sort-keys */
|
|
||||||
|
|
||||||
export const typesBundle = ${JSON.stringify(typesBundle, null, 2)} as unknown as OverrideBundleType;
|
export const typesBundle = ${JSON.stringify(typesBundle, null, 2)} as unknown as OverrideBundleType;
|
||||||
`);
|
`);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import type { OverrideBundleType } from '@pezkuwi/types/types';
|
|||||||
|
|
||||||
/* eslint-disable @stylistic/quotes */
|
/* eslint-disable @stylistic/quotes */
|
||||||
/* eslint-disable @stylistic/quote-props */
|
/* eslint-disable @stylistic/quote-props */
|
||||||
/* eslint-disable sort-keys */
|
|
||||||
|
|
||||||
export const typesBundle = {
|
export const typesBundle = {
|
||||||
"chain": {},
|
"chain": {},
|
||||||
|
|||||||
@@ -5,14 +5,12 @@
|
|||||||
import '@pezkuwi/api-augment/bizinikiwi';
|
import '@pezkuwi/api-augment/bizinikiwi';
|
||||||
|
|
||||||
import type { BN } from '@pezkuwi/util';
|
import type { BN } from '@pezkuwi/util';
|
||||||
import type { HexString } from '@pezkuwi/util/types';
|
|
||||||
|
|
||||||
import React, { useMemo, useRef } from 'react';
|
import React, { useMemo, useRef } from 'react';
|
||||||
import { Route, Routes } from 'react-router';
|
import { Route, Routes } from 'react-router';
|
||||||
|
|
||||||
import { getGenesis } from '@pezkuwi/apps-config';
|
|
||||||
import { Tabs } from '@pezkuwi/react-components';
|
import { Tabs } from '@pezkuwi/react-components';
|
||||||
import { useAccounts, useApi, useAssetIds, useAssetInfos } from '@pezkuwi/react-hooks';
|
import { useAccounts, useAssetIds, useAssetInfos } from '@pezkuwi/react-hooks';
|
||||||
import { BN_ONE } from '@pezkuwi/util';
|
import { BN_ONE } from '@pezkuwi/util';
|
||||||
|
|
||||||
import Balances from './Balances/index.js';
|
import Balances from './Balances/index.js';
|
||||||
@@ -27,18 +25,11 @@ interface Props {
|
|||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chains in which next asset id should be incremented from 1
|
function findOpenId (ids?: BN[]): BN {
|
||||||
const GENESIS_HASHES = [getGenesis('statemint'), getGenesis('statemine')];
|
|
||||||
|
|
||||||
function findOpenId (genesisHash: HexString, ids?: BN[]): BN {
|
|
||||||
if (!ids?.length) {
|
if (!ids?.length) {
|
||||||
return BN_ONE;
|
return BN_ONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GENESIS_HASHES.includes(genesisHash)) {
|
|
||||||
return ids.sort((a, b) => a.cmp(b))[ids.length - 1].add(BN_ONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
const lastTaken = ids.find((id, index) =>
|
const lastTaken = ids.find((id, index) =>
|
||||||
index === 0
|
index === 0
|
||||||
? !id.eq(BN_ONE)
|
? !id.eq(BN_ONE)
|
||||||
@@ -52,7 +43,6 @@ function findOpenId (genesisHash: HexString, ids?: BN[]): BN {
|
|||||||
|
|
||||||
function AssetApp ({ basePath, className }: Props): React.ReactElement<Props> {
|
function AssetApp ({ basePath, className }: Props): React.ReactElement<Props> {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { api } = useApi();
|
|
||||||
const { hasAccounts } = useAccounts();
|
const { hasAccounts } = useAccounts();
|
||||||
const ids = useAssetIds();
|
const ids = useAssetIds();
|
||||||
const infos = useAssetInfos(ids);
|
const infos = useAssetInfos(ids);
|
||||||
@@ -86,11 +76,9 @@ function AssetApp ({ basePath, className }: Props): React.ReactElement<Props> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const openId = useMemo(
|
const openId = useMemo(
|
||||||
() => findOpenId(
|
// Check if id is valid digit
|
||||||
api.genesisHash.toHex(),
|
() => findOpenId(ids?.filter((id) => /^\d{1,3}(,\d{3})*$/.test(id.toString()))),
|
||||||
// Check if id is valid digit
|
[ids]
|
||||||
ids?.filter((id) => /^\d{1,3}(,\d{3})*$/.test(id.toString()))),
|
|
||||||
[api.genesisHash, ids]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -137,11 +137,6 @@ function Row ({ chainRecord, highlight = false, id, lastCommittedTimeslice, leas
|
|||||||
$p={highlight}
|
$p={highlight}
|
||||||
className='media--800'
|
className='media--800'
|
||||||
>{<div style={{ alignItems: 'center', columnGap: '12px', display: 'flex', flexDirection: 'row', justifyContent: 'left' }}>
|
>{<div style={{ alignItems: 'center', columnGap: '12px', display: 'flex', flexDirection: 'row', justifyContent: 'left' }}>
|
||||||
<ParaLink
|
|
||||||
id={new BN(id)}
|
|
||||||
showLogo={false}
|
|
||||||
type={ParaLinkType.SUBSCAN}
|
|
||||||
/>
|
|
||||||
<div style={{ marginBottom: '2px' }}>
|
<div style={{ marginBottom: '2px' }}>
|
||||||
<ParaLink
|
<ParaLink
|
||||||
id={new BN(id)}
|
id={new BN(id)}
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
// Copyright 2017-2026 @pezkuwi/app-society authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import type { AccountId } from '@pezkuwi/types/interfaces';
|
|
||||||
|
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
|
||||||
|
|
||||||
import { DICLE_GENESIS } from '@pezkuwi/apps-config';
|
|
||||||
import { Button, Modal } from '@pezkuwi/react-components';
|
|
||||||
import { useApi, useToggle } from '@pezkuwi/react-hooks';
|
|
||||||
|
|
||||||
import drawCanary, { PADD, SIZE } from '../draw/canary.js';
|
|
||||||
import { useTranslation } from '../translate.js';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
accountId: AccountId;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CANVAS_STYLE = {
|
|
||||||
display: 'block',
|
|
||||||
margin: '0 auto'
|
|
||||||
};
|
|
||||||
|
|
||||||
const HEIGHT = (SIZE * 2) + (PADD * 1);
|
|
||||||
const WIDTH = (SIZE * 3) + (PADD * 2);
|
|
||||||
|
|
||||||
function DesignDicle ({ accountId }: Props): React.ReactElement<Props> | null {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const { api } = useApi();
|
|
||||||
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
|
||||||
const [onDicle] = useState(() => api.genesisHash.eq(DICLE_GENESIS));
|
|
||||||
const [isShowing, toggleDesign] = useToggle();
|
|
||||||
|
|
||||||
useEffect((): void => {
|
|
||||||
if (canvasRef.current) {
|
|
||||||
const ctx = canvasRef.current.getContext('2d');
|
|
||||||
|
|
||||||
if (ctx) {
|
|
||||||
drawCanary(ctx, accountId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!onDicle) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Button
|
|
||||||
icon='pen-nib'
|
|
||||||
onClick={toggleDesign}
|
|
||||||
/>
|
|
||||||
{isShowing && (
|
|
||||||
<Modal
|
|
||||||
header={t('design samples')}
|
|
||||||
onClose={toggleDesign}
|
|
||||||
size='large'
|
|
||||||
>
|
|
||||||
<Modal.Content>
|
|
||||||
<canvas
|
|
||||||
height={HEIGHT}
|
|
||||||
ref={canvasRef}
|
|
||||||
style={CANVAS_STYLE}
|
|
||||||
width={WIDTH}
|
|
||||||
/>
|
|
||||||
</Modal.Content>
|
|
||||||
</Modal>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default React.memo(DesignDicle);
|
|
||||||
@@ -13,7 +13,6 @@ import { BlockToTime, FormatBalance } from '@pezkuwi/react-query';
|
|||||||
import { formatNumber } from '@pezkuwi/util';
|
import { formatNumber } from '@pezkuwi/util';
|
||||||
|
|
||||||
import { useTranslation } from '../translate.js';
|
import { useTranslation } from '../translate.js';
|
||||||
import DesignDicle from './DesignDicle.js';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
bestNumber?: BN;
|
bestNumber?: BN;
|
||||||
@@ -141,9 +140,6 @@ function Member ({ bestNumber, className = '', value: { accountId, isCandidateVo
|
|||||||
</td>
|
</td>
|
||||||
<td className='together'>{votedOn}</td>
|
<td className='together'>{votedOn}</td>
|
||||||
<td className='number'>{formatNumber(strikes)}</td>
|
<td className='number'>{formatNumber(strikes)}</td>
|
||||||
<td className='button start'>
|
|
||||||
<DesignDicle accountId={accountId} />
|
|
||||||
</td>
|
|
||||||
</StyledTr>
|
</StyledTr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ function Members ({ className = '', mapMembers }: Props): React.ReactElement<Pro
|
|||||||
const headerRef = useRef<[React.ReactNode?, string?, number?][]>([
|
const headerRef = useRef<[React.ReactNode?, string?, number?][]>([
|
||||||
[t('members'), 'start', 2],
|
[t('members'), 'start', 2],
|
||||||
[t('voted on'), 'start'],
|
[t('voted on'), 'start'],
|
||||||
[t('strikes')],
|
[t('strikes')]
|
||||||
[]
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,216 +0,0 @@
|
|||||||
// Copyright 2017-2026 @pezkuwi/app-society authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
// Adapted (with permission) from https://www.w3schools.com/code/tryit.asp?filename=GGIGKE2GG7N1
|
|
||||||
|
|
||||||
import type { AccountId } from '@pezkuwi/types/interfaces';
|
|
||||||
|
|
||||||
// const DEFAULT_FN = (ctx: CanvasRenderingContext2D, path: Path2D) => ctx.fill(path);
|
|
||||||
export const PADD = 25;
|
|
||||||
export const SIZE = 300; // 250
|
|
||||||
|
|
||||||
function canary (ctx: CanvasRenderingContext2D, w: number, h: number, s: number, f: (ctx: CanvasRenderingContext2D, path: Path2D) => void): void {
|
|
||||||
const path = new Path2D('M373.1,126.9c-5.2-4.1-11.4-9.7-22.7-11.1c-10.6-1.4-21.4,5.7-28.7,10.4c-7.3,4.7-21.1,18.5-26.8,22.7 c-5.7,4.2-20.3,8.1-43.8,22.2s-115.7,73.3-115.7,73.3l24,0.3L52.4,299.8h10.7l-15.4,11.7c0,0,13.6,3.6,25-3.6l0,3.3 c0,0,127.4-50.2,152-37.2l-15,4.4c1.3,0,25.5,1.6,25.5,1.6s0.8,15.1,15.4,24.8c14.6,9.6,14.9,14.9,14.9,14.9s-7.6,3.1-7.6,7 c0,0,11.2-3.4,21.6-3.1c10.4,0.3,19.5,3.1,19.5,3.1s-0.8-4.2-10.9-7c-10.2-2.9-20.1-13.8-25-19.8c-4.9-6-8.3-16.7-4.1-27.4 c3.5-9.1,15.7-14.1,40.9-27.1c29.7-15.4,36.5-26.8,40.7-35.7c4.2-8.9,10.4-26.6,13.9-34.9c4.4-10.7,9.8-16.4,14.3-19.8 c4.4-3.4,24.5-10.9,24.5-10.9S378,130.8,373.1,126.9z');
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(w / 2, h / 2);
|
|
||||||
ctx.scale(s / 440, s / 440);
|
|
||||||
ctx.translate(-220, -220);
|
|
||||||
f(ctx, path);
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
function addressToBits (publicKey: Uint8Array): boolean[] {
|
|
||||||
return publicKey.reduce((bits: boolean[], byte): boolean[] => {
|
|
||||||
for (let j = 0; j < 8; ++j) {
|
|
||||||
bits.push((byte & (1 << (7 - j))) !== 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bits;
|
|
||||||
}, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ring (ctx: CanvasRenderingContext2D, r: number, bits: boolean[], f: (ctx: CanvasRenderingContext2D, on: boolean) => void): void {
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(0.5, 0.5);
|
|
||||||
|
|
||||||
for (let i = 0; i < bits.length; i++) {
|
|
||||||
ctx.save();
|
|
||||||
ctx.rotate(Math.PI * 2 / bits.length * i);
|
|
||||||
ctx.translate(0, -r);
|
|
||||||
f(ctx, bits[i]);
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
function splitRows (bits: boolean[], rows: number[]) {
|
|
||||||
let i = 0;
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-return-assign
|
|
||||||
return rows.map((r) => bits.slice(i, i += r));
|
|
||||||
}
|
|
||||||
|
|
||||||
function tattoo (ctx: CanvasRenderingContext2D, bits: boolean[]): void {
|
|
||||||
const rows = splitRows(bits, [71, 61, 51, 41, 32]);
|
|
||||||
|
|
||||||
for (let i = 0; i < rows.length; ++i) {
|
|
||||||
ring(ctx, 0.5 - (31 / 500) * (i + 0.5), rows[i], (ctx, on) => {
|
|
||||||
if (on) {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(0, 0, 8 / 500, 0, 2 * Math.PI);
|
|
||||||
ctx.fillStyle = 'black';
|
|
||||||
ctx.fill();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.lineWidth = 10;
|
|
||||||
canary(ctx, 1, 1, 200 / 500, (ctx, path) => ctx.stroke(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
function tattooSpiro (ctx: CanvasRenderingContext2D, bits: boolean[]): void {
|
|
||||||
const cycles = 8;
|
|
||||||
const limit = 0.75;
|
|
||||||
const dot = 8 / 500;
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(0.5 - dot, 0.5 + dot);
|
|
||||||
ctx.fillStyle = 'black';
|
|
||||||
|
|
||||||
let radius = 0.5 - dot;
|
|
||||||
|
|
||||||
for (let i = 0, count = bits.length; i < count; i++) {
|
|
||||||
radius -= 0.5 / count * limit / (radius * 4);
|
|
||||||
ctx.rotate(Math.PI * 2 / count * cycles / (radius * 4));
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(0, -radius);
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(0, 0, (bits[i] ? dot : dot / 2), 0, 2 * Math.PI);
|
|
||||||
ctx.fillStyle = bits[i] ? 'black' : '#86e62a';
|
|
||||||
ctx.fill();
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.restore();
|
|
||||||
ctx.lineWidth = 10;
|
|
||||||
canary(ctx, 1 - dot, 1 + dot, 220 / 500, (ctx, path) => ctx.stroke(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
function tattooPink (ctx: CanvasRenderingContext2D, bits: boolean[]): void {
|
|
||||||
const rows = splitRows(bits, [71, 61, 51, 41, 32]);
|
|
||||||
|
|
||||||
for (let i = 0; i < rows.length; ++i) {
|
|
||||||
ring(ctx, 0.5 - (31 / 500) * (i + 0.5), rows[i], (ctx, on) => {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(0, 0, (on ? 8 : 4) / 500, 0, 2 * Math.PI);
|
|
||||||
ctx.fillStyle = on ? 'black' : '#86e62a';
|
|
||||||
ctx.fill();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
canary(ctx, 1, 1, 220 / 500, (ctx, path) => ctx.fill(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
function tattoo2 (ctx: CanvasRenderingContext2D, bits: boolean[]): void {
|
|
||||||
const rows = splitRows(bits, [64, 64, 64, 64]);
|
|
||||||
|
|
||||||
for (let i = 0; i < rows.length; ++i) {
|
|
||||||
ring(ctx, 0.5 - (36 / 500) * (i + 0.5), rows[i], (ctx, on) => {
|
|
||||||
if (on) {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(0, -18 / 500);
|
|
||||||
ctx.lineTo(0, 18 / 500);
|
|
||||||
ctx.lineWidth = 0.01;
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
canary(ctx, 1, 1, 220 / 500, (ctx, path) => ctx.fill(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
function tattoo2b (ctx: CanvasRenderingContext2D, bits: boolean[]): void {
|
|
||||||
const rows = splitRows(bits, [128, 128]);
|
|
||||||
|
|
||||||
for (let i = 0; i < rows.length; ++i) {
|
|
||||||
ring(ctx, 0.5 - (36 / 500) * (i + 0.5), rows[i], (ctx, on) => {
|
|
||||||
if (on) {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(0, -18 / 500);
|
|
||||||
ctx.lineTo(0, 18 / 500);
|
|
||||||
ctx.lineWidth = 0.01;
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.lineWidth = 6;
|
|
||||||
canary(ctx, 1, 1, 350 / 500, (ctx, path) => ctx.stroke(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
function tattoo3 (ctx: CanvasRenderingContext2D, bits: boolean[]): void {
|
|
||||||
ctx.lineWidth = 0.01;
|
|
||||||
|
|
||||||
for (let i = 0; i < 8; ++i) {
|
|
||||||
for (let j = 0; j < 32; ++j) {
|
|
||||||
if (bits[i * 32 + j]) {
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate((j + 0.5) / 32, i / 8);
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(0, 0);
|
|
||||||
ctx.lineTo(0, 1 / 8);
|
|
||||||
ctx.stroke();
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
|
|
||||||
canary(ctx, 1, 1, 1, (ctx, path) => ctx.fill(path));
|
|
||||||
ctx.lineWidth = 6;
|
|
||||||
canary(ctx, 1, 1, 1, (ctx, path) => ctx.stroke(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function draw (ctx: CanvasRenderingContext2D, accountId: AccountId): void {
|
|
||||||
console.log(`Generating ink for ${accountId.toString()} as ${accountId.toHex()}`);
|
|
||||||
|
|
||||||
const bits = addressToBits(accountId.toU8a());
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(0, 0);
|
|
||||||
ctx.scale(SIZE, SIZE);
|
|
||||||
tattoo(ctx, bits);
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(SIZE + PADD, 0);
|
|
||||||
ctx.scale(SIZE, SIZE);
|
|
||||||
tattooPink(ctx, bits);
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(0, SIZE + PADD);
|
|
||||||
ctx.scale(SIZE, SIZE);
|
|
||||||
tattoo2(ctx, bits);
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(SIZE + PADD, SIZE + PADD);
|
|
||||||
ctx.scale(SIZE, SIZE);
|
|
||||||
tattoo3(ctx, bits);
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate((SIZE + PADD) * 2, 0);
|
|
||||||
ctx.scale(SIZE, SIZE);
|
|
||||||
tattooSpiro(ctx, bits);
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate((SIZE + PADD) * 2, SIZE + PADD);
|
|
||||||
ctx.scale(SIZE, SIZE);
|
|
||||||
tattoo2b(ctx, bits);
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,6 @@ import type { BN } from '@pezkuwi/util';
|
|||||||
|
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
|
|
||||||
import { Subscan } from '@pezkuwi/apps-config/links/subscan';
|
|
||||||
import { useParaEndpoints } from '@pezkuwi/react-hooks';
|
import { useParaEndpoints } from '@pezkuwi/react-hooks';
|
||||||
|
|
||||||
import ChainImg from './ChainImg.js';
|
import ChainImg from './ChainImg.js';
|
||||||
@@ -14,8 +13,7 @@ import { styled } from './styled.js';
|
|||||||
|
|
||||||
export enum ParaLinkType {
|
export enum ParaLinkType {
|
||||||
PJS = 'pjs',
|
PJS = 'pjs',
|
||||||
HOME = 'home',
|
HOME = 'home'
|
||||||
SUBSCAN = 'subscan'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -40,11 +38,6 @@ function ParaLink ({ className, id, showLogo = true, type = ParaLinkType.PJS }:
|
|||||||
? links[links.length - 1]
|
? links[links.length - 1]
|
||||||
: endpoints[0];
|
: endpoints[0];
|
||||||
|
|
||||||
const subscanUrl = text &&
|
|
||||||
typeof text === 'string' &&
|
|
||||||
Subscan.chains[text] &&
|
|
||||||
Subscan.create(Subscan.chains[text], '', '').toString();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledDiv className={className}>
|
<StyledDiv className={className}>
|
||||||
{showLogo && (
|
{showLogo && (
|
||||||
@@ -57,19 +50,6 @@ function ParaLink ({ className, id, showLogo = true, type = ParaLinkType.PJS }:
|
|||||||
{links.length
|
{links.length
|
||||||
? (
|
? (
|
||||||
<>
|
<>
|
||||||
{type === ParaLinkType.SUBSCAN && !!subscanUrl && (
|
|
||||||
<a
|
|
||||||
href={subscanUrl}
|
|
||||||
rel='noopener noreferrer'
|
|
||||||
target='_blank'
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt='Subscan'
|
|
||||||
height='20'
|
|
||||||
src={Subscan.ui.logo}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
{type === ParaLinkType.HOME && homepage && (
|
{type === ParaLinkType.HOME && homepage && (
|
||||||
<a
|
<a
|
||||||
href={homepage}
|
href={homepage}
|
||||||
|
|||||||
Reference in new issue
Block a user