Skip to content

Commit e481b36

Browse files
feat(statics): expose bech32 HRP via AccountNetwork.addressPrefix
Add optional `addressPrefix?: string` to `AccountNetwork` interface so downstream consumers (e.g. the BFF address-poisoning detector, WCN-607) can strip well-known bech32 HRPs before Levenshtein comparison. `CosmosNetwork` already requires `addressPrefix: string`; adding the optional field to its parent `AccountNetwork` is purely additive. Populate the new field for all Cosmos-family AccountNetwork classes that previously hid their HRP in per-coin constants.ts files. All values verified against github.com/cosmos/chain-registry. Mainnet+testnet (same HRP): - atom -> cosmos - osmo -> osmo - sei -> sei - tia -> celestia - baby -> bbn - bld -> agoric - initia -> init - zeta -> zeta - asi -> fetch - islm -> haqq - injective -> inj Mainnet/testnet (asymmetric): - hash -> pb / tp - coreum -> core / testcore - cronos -> cro / tcro - rune -> thor / sthor kava/dydx/mantra already have addressPrefix via CosmosNetwork; tests added for completeness. fetchai is deprecated -- skipped. Ticket: WCN-606
1 parent eaba1c2 commit e481b36

2 files changed

Lines changed: 80 additions & 1 deletion

File tree

modules/statics/src/networks.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ export interface AccountNetwork extends BaseNetwork {
122122
// is a url that can be used to look up the account for the gas tank on-chain.
123123
readonly accountExplorerUrl?: string;
124124
readonly blockExplorerUrl?: string;
125+
// bech32 HRP for chains that use one (e.g. Cosmos-family coins)
126+
readonly addressPrefix?: string;
125127
}
126128

127129
export interface CosmosNetwork extends AccountNetwork {
@@ -978,96 +980,112 @@ class Atom extends Mainnet implements AccountNetwork {
978980
name = 'Cosmos Hub ATOM';
979981
family = CoinFamily.ATOM;
980982
explorerUrl = 'https://www.mintscan.io/cosmos/tx/';
983+
addressPrefix = 'cosmos';
981984
}
982985

983986
class AtomTestnet extends Testnet implements AccountNetwork {
984987
name = 'Testnet Cosmos Hub ATOM';
985988
family = CoinFamily.ATOM;
986989
explorerUrl = 'https://explorer.polypore.xyz/provider/tx/';
990+
addressPrefix = 'cosmos';
987991
}
988992

989993
class Osmo extends Mainnet implements AccountNetwork {
990994
name = 'Osmosis';
991995
family = CoinFamily.OSMO;
992996
explorerUrl = 'https://www.mintscan.io/osmosis/txs/';
997+
addressPrefix = 'osmo';
993998
}
994999

9951000
class OsmoTestnet extends Testnet implements AccountNetwork {
9961001
name = 'Testnet Osmosis';
9971002
family = CoinFamily.OSMO;
9981003
explorerUrl = 'https://testnet.osmosis.explorers.guru/transaction/';
1004+
addressPrefix = 'osmo';
9991005
}
10001006

10011007
class Tia extends Mainnet implements AccountNetwork {
10021008
name = 'Celestia';
10031009
family = CoinFamily.TIA;
10041010
explorerUrl = 'https://www.mintscan.io/celestia/tx/';
1011+
addressPrefix = 'celestia';
10051012
}
10061013

10071014
class TiaTestnet extends Testnet implements AccountNetwork {
10081015
name = 'Testnet Celestia';
10091016
family = CoinFamily.TIA;
10101017
explorerUrl = 'https://testnet.celestia.explorers.guru/transaction/';
1018+
addressPrefix = 'celestia';
10111019
}
10121020

10131021
class Hash extends Mainnet implements AccountNetwork {
10141022
name = 'Provenance';
10151023
family = CoinFamily.HASH;
10161024
explorerUrl = 'https://explorer.provenance.io/tx/';
1025+
addressPrefix = 'pb';
10171026
}
10181027

10191028
class HashTestnet extends Testnet implements AccountNetwork {
10201029
name = 'Testnet Provenance';
10211030
family = CoinFamily.HASH;
10221031
explorerUrl = 'https://explorer.test.provenance.io/tx/';
1032+
addressPrefix = 'tp';
10231033
}
10241034

10251035
class Bld extends Mainnet implements AccountNetwork {
10261036
name = 'Agoric';
10271037
family = CoinFamily.BLD;
10281038
explorerUrl = 'https://bigdipper.live/agoric/transactions/';
1039+
addressPrefix = 'agoric';
10291040
}
10301041

10311042
class BldTestnet extends Testnet implements AccountNetwork {
10321043
name = 'Testnet Agoric';
10331044
family = CoinFamily.BLD;
10341045
explorerUrl = 'https://emerynet.explorer.agoric.net/agoric/tx/';
1046+
addressPrefix = 'agoric';
10351047
}
10361048

10371049
class Sei extends Mainnet implements AccountNetwork {
10381050
name = 'Sei';
10391051
family = CoinFamily.SEI;
10401052
explorerUrl = 'https://mintscan.io/sei/tx/';
1053+
addressPrefix = 'sei';
10411054
}
10421055

10431056
class SeiTestnet extends Testnet implements AccountNetwork {
10441057
name = 'Testnet Sei';
10451058
family = CoinFamily.SEI;
10461059
explorerUrl = 'https://testnet.seitrace.com/tx/';
1060+
addressPrefix = 'sei';
10471061
}
10481062

10491063
class Zeta extends Mainnet implements AccountNetwork {
10501064
name = 'Zeta';
10511065
family = CoinFamily.ZETA;
10521066
explorerUrl = 'https://explorer.zetachain.com/cosmos/tx/';
1067+
addressPrefix = 'zeta';
10531068
}
10541069

10551070
class ZetaTestnet extends Testnet implements AccountNetwork {
10561071
name = 'Testnet Zeta';
10571072
family = CoinFamily.ZETA;
10581073
explorerUrl = 'https://athens.explorer.zetachain.com/cosmos/tx/';
1074+
addressPrefix = 'zeta';
10591075
}
10601076

10611077
class Injective extends Mainnet implements AccountNetwork {
10621078
name = 'Injective';
10631079
family = CoinFamily.INJECTIVE;
10641080
explorerUrl = 'https://www.mintscan.io/injective/tx/';
1081+
addressPrefix = 'inj';
10651082
}
10661083

10671084
class InjectiveTestnet extends Testnet implements AccountNetwork {
10681085
name = 'InjectiveTestnet';
10691086
family = CoinFamily.INJECTIVE;
10701087
explorerUrl = 'https://testnet.explorer.injective.network/transaction/';
1088+
addressPrefix = 'inj';
10711089
}
10721090

10731091
class KavaCosmos extends Mainnet implements CosmosNetwork {
@@ -1134,36 +1152,42 @@ class Coreum extends Mainnet implements AccountNetwork {
11341152
name = 'TX';
11351153
family = CoinFamily.COREUM;
11361154
explorerUrl = 'https://explorer.tx.org/tx/transactions/';
1155+
addressPrefix = 'core';
11371156
}
11381157

11391158
class CoreumTestnet extends Testnet implements AccountNetwork {
11401159
name = 'Testnet TX';
11411160
family = CoinFamily.COREUM;
11421161
explorerUrl = 'https://explorer.testnet-1.tx.org/tx/transactions/';
1162+
addressPrefix = 'testcore';
11431163
}
11441164

11451165
class Rune extends Mainnet implements AccountNetwork {
11461166
name = 'Rune';
11471167
family = CoinFamily.THOR;
11481168
explorerUrl = 'https://runescan.io/tx/';
1169+
addressPrefix = 'thor';
11491170
}
11501171

11511172
class RuneTestNet extends Testnet implements AccountNetwork {
11521173
name = 'RuneTestNet';
11531174
family = CoinFamily.THOR;
11541175
explorerUrl = 'https://runescan.io/tx/?network=stagenet';
1176+
addressPrefix = 'sthor';
11551177
}
11561178

11571179
class Baby extends Mainnet implements AccountNetwork {
11581180
name = 'Babylon';
11591181
family = CoinFamily.BABY;
11601182
explorerUrl = 'https://www.mintscan.io/babylon/tx/';
1183+
addressPrefix = 'bbn';
11611184
}
11621185

11631186
class BabyTestnet extends Testnet implements AccountNetwork {
11641187
name = 'Testnet Babylon';
11651188
family = CoinFamily.BABY;
11661189
explorerUrl = 'https://www.mintscan.io/babylon-testnet/tx/';
1190+
addressPrefix = 'bbn';
11671191
}
11681192

11691193
class Mantra extends Mainnet implements CosmosNetwork {
@@ -1194,12 +1218,14 @@ class Cronos extends Mainnet implements AccountNetwork {
11941218
name = 'Cronos POS';
11951219
family = CoinFamily.CRONOS;
11961220
explorerUrl = 'https://cronos-pos.org/explorer/tx/';
1221+
addressPrefix = 'cro';
11971222
}
11981223

11991224
class CronosTestnet extends Testnet implements AccountNetwork {
12001225
name = 'Testnet Cronos POS';
12011226
family = CoinFamily.CRONOS;
12021227
explorerUrl = 'https://cronos-pos.org/explorer/croeseid4/tx/';
1228+
addressPrefix = 'tcro';
12031229
}
12041230

12051231
class FetchAi extends Mainnet implements AccountNetwork {
@@ -1218,36 +1244,42 @@ class Initia extends Mainnet implements AccountNetwork {
12181244
name = 'Initia';
12191245
family = CoinFamily.INITIA;
12201246
explorerUrl = 'https://scan.initia.xyz/interwoven-1/txs/';
1247+
addressPrefix = 'init';
12211248
}
12221249

12231250
class InitiaTestnet extends Testnet implements AccountNetwork {
12241251
name = 'Testnet Initia';
12251252
family = CoinFamily.INITIA;
12261253
explorerUrl = 'https://scan.testnet.initia.xyz/initiation-2/txs/';
1254+
addressPrefix = 'init';
12271255
}
12281256

12291257
class Asi extends Mainnet implements AccountNetwork {
12301258
name = 'Fetch Native';
12311259
family = CoinFamily.ASI;
12321260
explorerUrl = 'https://companion.fetch.ai/fetchhub-4/transactions/';
1261+
addressPrefix = 'fetch';
12331262
}
12341263

12351264
class AsiTestnet extends Testnet implements AccountNetwork {
12361265
name = 'Testnet Fetch Native';
12371266
family = CoinFamily.ASI;
12381267
explorerUrl = 'https://companion.fetch.ai/dorado-1/transactions/';
1268+
addressPrefix = 'fetch';
12391269
}
12401270

12411271
class Islm extends Mainnet implements AccountNetwork {
12421272
name = 'Haqq';
12431273
family = CoinFamily.ISLM;
12441274
explorerUrl = 'https://ping.pub/haqq/tx/';
1275+
addressPrefix = 'haqq';
12451276
}
12461277

12471278
class IslmTestnet extends Testnet implements AccountNetwork {
12481279
name = 'HaqqTestnet';
12491280
family = CoinFamily.ISLM;
12501281
explorerUrl = 'https://testnet.ping.pub/haqq/tx/';
1282+
addressPrefix = 'haqq';
12511283
}
12521284

12531285
class Stx extends Mainnet implements StacksNetwork {

modules/statics/test/unit/networks.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import 'should';
2-
import { BaseNetwork, DynamicNetwork, getNetwork, Networks, NetworkType } from '../../src/networks';
2+
import { AccountNetwork, BaseNetwork, DynamicNetwork, getNetwork, Networks, NetworkType } from '../../src/networks';
33

44
Object.entries(Networks).forEach(([category, networks]) => {
55
Object.entries(networks).forEach(([networkName, network]) => {
@@ -73,6 +73,53 @@ Object.entries(Networks).forEach(([category, networks]) => {
7373
});
7474
});
7575

76+
describe('Cosmos-family addressPrefix', function () {
77+
const cases: Array<[string, AccountNetwork, string]> = [
78+
['main.atom', Networks.main.atom, 'cosmos'],
79+
['test.atom', Networks.test.atom, 'cosmos'],
80+
['main.osmo', Networks.main.osmo, 'osmo'],
81+
['test.osmo', Networks.test.osmo, 'osmo'],
82+
['main.sei', Networks.main.sei, 'sei'],
83+
['test.sei', Networks.test.sei, 'sei'],
84+
['main.tia', Networks.main.tia, 'celestia'],
85+
['test.tia', Networks.test.tia, 'celestia'],
86+
['main.baby', Networks.main.baby, 'bbn'],
87+
['test.baby', Networks.test.baby, 'bbn'],
88+
['main.bld', Networks.main.bld, 'agoric'],
89+
['test.bld', Networks.test.bld, 'agoric'],
90+
['main.initia', Networks.main.initia, 'init'],
91+
['test.initia', Networks.test.initia, 'init'],
92+
['main.zeta', Networks.main.zeta, 'zeta'],
93+
['test.zeta', Networks.test.zeta, 'zeta'],
94+
['main.asi', Networks.main.asi, 'fetch'],
95+
['test.asi', Networks.test.asi, 'fetch'],
96+
['main.islm', Networks.main.islm, 'haqq'],
97+
['test.islm', Networks.test.islm, 'haqq'],
98+
['main.injective', Networks.main.injective, 'inj'],
99+
['test.injective', Networks.test.injective, 'inj'],
100+
['main.hash', Networks.main.hash, 'pb'],
101+
['test.hash', Networks.test.hash, 'tp'],
102+
['main.coreum', Networks.main.coreum, 'core'],
103+
['test.coreum', Networks.test.coreum, 'testcore'],
104+
['main.cronos', Networks.main.cronos, 'cro'],
105+
['test.cronos', Networks.test.cronos, 'tcro'],
106+
['main.rune', Networks.main.rune, 'thor'],
107+
['test.rune', Networks.test.rune, 'sthor'],
108+
['main.mantra', Networks.main.mantra, 'mantra'],
109+
['test.mantra', Networks.test.mantra, 'mantra'],
110+
['main.kavacosmos', Networks.main.kavacosmos, 'kava'],
111+
['test.kavacosmos', Networks.test.kavacosmos, 'kava'],
112+
['main.dydx', Networks.main.dydx, 'dydx'],
113+
['test.dydx', Networks.test.dydx, 'dydx'],
114+
];
115+
116+
for (const [label, network, hrp] of cases) {
117+
it(`Networks.${label} has addressPrefix '${hrp}'`, function () {
118+
network.should.have.property('addressPrefix', hrp);
119+
});
120+
}
121+
});
122+
76123
describe('DynamicNetwork and getNetwork', function () {
77124
it('DynamicNetwork should be an instance of BaseNetwork', function () {
78125
const network = new DynamicNetwork({ name: 'TestDynNet', type: 'testnet', family: 'eth' });

0 commit comments

Comments
 (0)