@shapeshiftoss/caip 8.15.0 → 8.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/CHANGELOG.md +726 -0
  2. package/dist/accountId/accountId.d.ts +9 -9
  3. package/dist/accountId/accountId.js +16 -20
  4. package/dist/accountId/accountId.test.js +107 -0
  5. package/dist/adapters/banxa/index.d.ts +6 -5
  6. package/dist/adapters/banxa/index.js +60 -38
  7. package/dist/adapters/coinbase/generate.js +4 -8
  8. package/dist/adapters/coinbase/generated/index.js +2 -8
  9. package/dist/adapters/coinbase/index.d.ts +1 -1
  10. package/dist/adapters/coinbase/index.js +7 -15
  11. package/dist/adapters/coinbase/utils.d.ts +2 -2
  12. package/dist/adapters/coinbase/utils.js +11 -23
  13. package/dist/adapters/coincap/generate.js +5 -7
  14. package/dist/adapters/coincap/generated/cosmos_thorchain-1/adapter.json +1 -0
  15. package/dist/adapters/coincap/generated/eip155_1/adapter.json +1 -1
  16. package/dist/adapters/coincap/generated/index.d.ts +2 -3
  17. package/dist/adapters/coincap/generated/index.js +8 -22
  18. package/dist/adapters/coincap/index.d.ts +2 -1
  19. package/dist/adapters/coincap/index.js +9 -38
  20. package/dist/adapters/coincap/index.test.js +92 -0
  21. package/dist/adapters/coincap/utils.d.ts +1 -1
  22. package/dist/adapters/coincap/utils.js +21 -32
  23. package/dist/adapters/coincap/utils.test.d.ts +4 -0
  24. package/dist/adapters/coincap/utils.test.js +163 -0
  25. package/dist/adapters/coingecko/generate.js +5 -7
  26. package/dist/adapters/coingecko/generated/cosmos_mayachain-mainnet-v1/adapter.json +1 -0
  27. package/dist/adapters/coingecko/generated/cosmos_thorchain-1/adapter.json +1 -0
  28. package/dist/adapters/coingecko/generated/eip155_1/adapter.json +1 -1
  29. package/dist/adapters/coingecko/generated/eip155_10/adapter.json +1 -1
  30. package/dist/adapters/coingecko/generated/eip155_100/adapter.json +1 -0
  31. package/dist/adapters/coingecko/generated/eip155_137/adapter.json +1 -0
  32. package/dist/adapters/coingecko/generated/eip155_42161/adapter.json +1 -0
  33. package/dist/adapters/coingecko/generated/eip155_42170/adapter.json +1 -0
  34. package/dist/adapters/coingecko/generated/eip155_43114/adapter.json +1 -1
  35. package/dist/adapters/coingecko/generated/eip155_56/adapter.json +1 -1
  36. package/dist/adapters/coingecko/generated/eip155_8453/adapter.json +1 -0
  37. package/dist/adapters/coingecko/generated/index.d.ts +9 -3
  38. package/dist/adapters/coingecko/generated/index.js +18 -28
  39. package/dist/adapters/coingecko/generated/solana_5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/adapter.json +1 -0
  40. package/dist/adapters/coingecko/index.d.ts +16 -14
  41. package/dist/adapters/coingecko/index.js +87 -73
  42. package/dist/adapters/coingecko/index.test.d.ts +1 -0
  43. package/dist/adapters/coingecko/index.test.js +274 -0
  44. package/dist/adapters/coingecko/utils.d.ts +4 -6
  45. package/dist/adapters/coingecko/utils.js +141 -59
  46. package/dist/adapters/coingecko/utils.test.d.ts +1 -0
  47. package/dist/adapters/coingecko/utils.test.js +188 -0
  48. package/dist/adapters/index.d.ts +0 -5
  49. package/dist/adapters/index.js +6 -27
  50. package/dist/adapters/mtpelerin/index.d.ts +1 -61
  51. package/dist/adapters/mtpelerin/index.js +96 -88
  52. package/dist/adapters/onramper/index.d.ts +2 -2
  53. package/dist/adapters/onramper/index.js +1483 -62
  54. package/dist/assetId/assetId.d.ts +14 -13
  55. package/dist/assetId/assetId.js +81 -57
  56. package/dist/assetId/assetId.test.d.ts +1 -0
  57. package/dist/assetId/assetId.test.js +336 -0
  58. package/dist/chainId/chainId.d.ts +11 -10
  59. package/dist/chainId/chainId.js +14 -16
  60. package/dist/chainId/chainId.test.d.ts +1 -0
  61. package/dist/chainId/chainId.test.js +88 -0
  62. package/dist/constants.d.ts +57 -38
  63. package/dist/constants.js +135 -108
  64. package/dist/index.js +7 -36
  65. package/dist/typeGuards.d.ts +5 -3
  66. package/dist/typeGuards.js +34 -40
  67. package/dist/utils.d.ts +7 -8
  68. package/dist/utils.js +23 -67
  69. package/dist/utils.test.d.ts +1 -0
  70. package/dist/utils.test.js +162 -0
  71. package/package.json +11 -30
  72. package/dist/adapters/coincap/generated/cosmos_osmosis-1/adapter.json +0 -1
  73. package/dist/adapters/coincap/generated/cosmos_thorchain-mainnet-v1/adapter.json +0 -1
  74. package/dist/adapters/coingecko/generated/cosmos_osmosis-1/adapter.json +0 -1
  75. package/dist/adapters/coingecko/generated/cosmos_thorchain-mainnet-v1/adapter.json +0 -1
  76. package/dist/adapters/gem/index.d.ts +0 -2
  77. package/dist/adapters/gem/index.js +0 -39
  78. package/dist/adapters/junopay/index.d.ts +0 -7
  79. package/dist/adapters/junopay/index.js +0 -52
  80. package/dist/adapters/osmosis/generate.js +0 -13
  81. package/dist/adapters/osmosis/generated/cosmos_osmosis-1/adapter.json +0 -1022
  82. package/dist/adapters/osmosis/generated/index.d.ts +0 -2
  83. package/dist/adapters/osmosis/generated/index.js +0 -8
  84. package/dist/adapters/osmosis/index.d.ts +0 -6
  85. package/dist/adapters/osmosis/index.js +0 -54
  86. package/dist/adapters/osmosis/utils.d.ts +0 -37
  87. package/dist/adapters/osmosis/utils.js +0 -90
  88. package/dist/adapters/thortrading/index.d.ts +0 -5
  89. package/dist/adapters/thortrading/index.js +0 -44
  90. package/dist/adapters/yearn/generate.js +0 -9
  91. package/dist/adapters/yearn/generated/eip155_1/adapter.json +0 -1
  92. package/dist/adapters/yearn/generated/index.d.ts +0 -2
  93. package/dist/adapters/yearn/generated/index.js +0 -8
  94. package/dist/adapters/yearn/index.d.ts +0 -2
  95. package/dist/adapters/yearn/index.js +0 -41
  96. package/dist/adapters/yearn/utils.d.ts +0 -7
  97. package/dist/adapters/yearn/utils.js +0 -62
  98. /package/dist/{adapters/osmosis/generate.d.ts → accountId/accountId.test.d.ts} +0 -0
  99. /package/dist/adapters/{yearn/generate.d.ts → coincap/index.test.d.ts} +0 -0
@@ -1,35 +1,36 @@
1
- import { ChainId, ChainNamespace, ChainReference } from '../chainId/chainId';
2
- import { ASSET_NAMESPACE, ASSET_REFERENCE } from '../constants';
3
- import { Nominal } from '../utils';
4
- export declare type AssetId = Nominal<string, 'AssetId'>;
5
- export declare type AssetNamespace = typeof ASSET_NAMESPACE[keyof typeof ASSET_NAMESPACE];
6
- export declare type AssetReference = typeof ASSET_REFERENCE[keyof typeof ASSET_REFERENCE];
7
- declare type ToAssetIdWithChainId = {
1
+ import type { ChainId, ChainNamespace, ChainReference } from '../chainId/chainId';
2
+ import type { ASSET_NAMESPACE, ASSET_REFERENCE } from '../constants';
3
+ import type { Nominal } from '../utils';
4
+ export type AssetId = Nominal<string, 'AssetId'>;
5
+ export type AssetNamespace = (typeof ASSET_NAMESPACE)[keyof typeof ASSET_NAMESPACE];
6
+ export type AssetReference = (typeof ASSET_REFERENCE)[keyof typeof ASSET_REFERENCE];
7
+ type ToAssetIdWithChainId = {
8
8
  chainNamespace?: never;
9
9
  chainReference?: never;
10
10
  chainId: ChainId;
11
11
  assetNamespace: AssetNamespace;
12
12
  assetReference: AssetReference | string;
13
13
  };
14
- declare type ToAssetIdWithChainIdParts = {
14
+ type ToAssetIdWithChainIdParts = {
15
15
  chainNamespace: ChainNamespace;
16
16
  chainReference: ChainReference;
17
17
  chainId?: never;
18
18
  assetNamespace: AssetNamespace;
19
19
  assetReference: AssetReference | string;
20
20
  };
21
- export declare type ToAssetIdArgs = ToAssetIdWithChainId | ToAssetIdWithChainIdParts;
22
- declare type ToAssetId = (args: ToAssetIdArgs) => AssetId;
21
+ export type ToAssetIdArgs = ToAssetIdWithChainId | ToAssetIdWithChainIdParts;
22
+ type ToAssetId = (args: ToAssetIdArgs) => AssetId;
23
23
  export declare const toAssetId: ToAssetId;
24
- declare type FromAssetIdReturn = {
24
+ type FromAssetIdReturn = {
25
25
  chainNamespace: ChainNamespace;
26
26
  chainReference: ChainReference;
27
27
  chainId: ChainId;
28
28
  assetNamespace: AssetNamespace;
29
- assetReference: AssetReference | string;
29
+ assetReference: AssetReference;
30
30
  };
31
- export declare type FromAssetId = (assetId: AssetId) => FromAssetIdReturn;
31
+ export type FromAssetId = (assetId: AssetId) => FromAssetIdReturn;
32
32
  export declare const fromAssetId: FromAssetId;
33
+ export declare const isNft: (assetId: AssetId) => boolean;
33
34
  export declare const toCAIP19: ToAssetId;
34
35
  export declare const fromCAIP19: FromAssetId;
35
36
  export {};
@@ -1,30 +1,29 @@
1
- "use strict";
2
1
  // https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-19.md
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.fromCAIP19 = exports.toCAIP19 = exports.fromAssetId = exports.toAssetId = void 0;
5
- const chainId_1 = require("../chainId/chainId");
6
- const constants_1 = require("../constants");
7
- const typeGuards_1 = require("../typeGuards");
8
- const utils_1 = require("../utils");
2
+ import { fromChainId, toChainId } from '../chainId/chainId';
3
+ import { VALID_ASSET_NAMESPACE } from '../constants';
4
+ import { assertIsAssetNamespace, assertIsChainNamespace, assertIsChainReference, assertValidChainPartsPair, isAssetIdParts, isAssetNamespace, } from '../typeGuards';
9
5
  /**
10
6
  * validate that a value is a string slip44 value
11
7
  * @see https://github.com/satoshilabs/slips/blob/master/slip-0044.md
12
8
  * @param {string} value - possible slip44 value
13
9
  */
14
10
  const isValidSlip44 = (value) => {
11
+ // TCY is a weird AssetId, its asset ref part is not a number
12
+ if (value === 'tcy')
13
+ return true;
15
14
  const n = Number(value);
16
15
  // slip44 has a max value of an unsigned 32-bit integer
17
16
  return !isNaN(n) && n >= 0 && n < 4294967296;
18
17
  };
19
18
  const isToAssetIdWithChainIdArgs = (args) => !!args.chainId;
20
- const toAssetId = (args) => {
19
+ export const toAssetId = (args) => {
21
20
  const { assetNamespace, assetReference } = args;
22
- (0, typeGuards_1.assertIsAssetNamespace)(assetNamespace);
21
+ assertIsAssetNamespace(assetNamespace);
23
22
  if (!assetReference)
24
23
  throw new Error('toAssetId: No assetReference provided');
25
24
  const { chainId, chainNamespace, chainReference } = (() => {
26
25
  if (isToAssetIdWithChainIdArgs(args)) {
27
- const fromChainIdResult = (0, chainId_1.fromChainId)(args.chainId);
26
+ const fromChainIdResult = fromChainId(args.chainId);
28
27
  return {
29
28
  chainId: args.chainId,
30
29
  chainNamespace: fromChainIdResult.chainNamespace,
@@ -33,7 +32,7 @@ const toAssetId = (args) => {
33
32
  }
34
33
  else
35
34
  return {
36
- chainId: (0, chainId_1.toChainId)({
35
+ chainId: toChainId({
37
36
  chainNamespace: args.chainNamespace,
38
37
  chainReference: args.chainReference,
39
38
  }),
@@ -41,56 +40,81 @@ const toAssetId = (args) => {
41
40
  chainReference: args.chainReference,
42
41
  };
43
42
  })();
44
- const isContractAddress = Array('erc20', 'erc721', 'bep20', 'bep721').includes(assetNamespace);
45
- (0, typeGuards_1.assertIsChainNamespace)(chainNamespace);
46
- (0, typeGuards_1.assertIsChainReference)(chainReference);
47
- (0, typeGuards_1.assertValidChainPartsPair)(chainNamespace, chainReference);
48
- if (!constants_1.VALID_ASSET_NAMESPACE[chainNamespace].includes(assetNamespace) ||
49
- !(0, typeGuards_1.isAssetNamespace)(assetNamespace))
43
+ assertIsChainNamespace(chainNamespace);
44
+ assertIsChainReference(chainReference);
45
+ assertValidChainPartsPair(chainNamespace, chainReference);
46
+ if (!VALID_ASSET_NAMESPACE[chainNamespace].includes(assetNamespace) ||
47
+ !isAssetNamespace(assetNamespace))
50
48
  throw new Error(`toAssetId: AssetNamespace ${assetNamespace} not supported for Chain Namespace ${chainNamespace}`);
51
49
  if (assetNamespace === 'slip44' && !isValidSlip44(String(assetReference))) {
52
50
  throw new Error(`Invalid reference for namespace slip44`);
53
51
  }
54
- if (isContractAddress) {
55
- if (!assetReference.startsWith('0x'))
56
- throw new Error(`toAssetId: assetReference must start with 0x: ${assetReference}`);
57
- if (assetReference.length !== 42)
58
- throw new Error(`toAssetId: assetReference length must be 42, length: ${assetReference.length}`);
59
- }
60
- // We make Eth contract addresses lower case to simplify comparisons
61
- const assetReferenceCaseCorrected = isContractAddress
62
- ? assetReference.toLowerCase()
63
- : assetReference;
64
- return `${chainId}/${assetNamespace}:${assetReferenceCaseCorrected}`;
65
- };
66
- exports.toAssetId = toAssetId;
67
- const fromAssetId = (assetId) => {
68
- if (!(0, typeGuards_1.isAssetId)(assetId))
69
- throw new Error(`fromAssetId: invalid AssetId: ${assetId}`);
70
- const matches = utils_1.parseAssetIdRegExp.exec(assetId);
71
- if (!matches)
72
- throw new Error(`fromAssetId: could not parse AssetId: ${assetId}`);
73
- const { 1: chainNamespace, 2: chainReference, 3: assetNamespace, 4: assetReference } = matches;
74
- // These should never throw because isAssetId() would have already caught it, but they help with type inference
75
- (0, typeGuards_1.assertIsChainNamespace)(chainNamespace);
76
- (0, typeGuards_1.assertIsChainReference)(chainReference);
77
- (0, typeGuards_1.assertIsAssetNamespace)(assetNamespace);
78
- const chainId = (0, chainId_1.toChainId)({ chainNamespace, chainReference });
79
- if (assetNamespace && assetReference && chainId) {
80
- return {
81
- chainId,
82
- chainReference,
83
- chainNamespace,
84
- assetNamespace,
85
- assetReference: ['erc20', 'erc721', 'bep20', 'bep721'].includes(assetNamespace)
86
- ? assetReference.toLowerCase()
87
- : assetReference,
52
+ const assetReferenceNormalized = (() => {
53
+ const assertContractAddress = (address) => {
54
+ if (!address.startsWith('0x'))
55
+ throw new Error(`toAssetId: assetReference must start with 0x: ${assetReference}`);
56
+ if (address.length !== 42)
57
+ throw new Error(`toAssetId: assetReference length must be 42, length: ${assetReference.length}, ${assetReference}`);
88
58
  };
89
- }
90
- else {
59
+ switch (assetNamespace) {
60
+ case 'erc20':
61
+ case 'bep20':
62
+ assertContractAddress(assetReference);
63
+ return assetReference.toLowerCase();
64
+ case 'erc721':
65
+ case 'erc1155':
66
+ case 'bep721':
67
+ case 'bep1155':
68
+ // caip-22 (https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-22.md)
69
+ // caip-29 (https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-29.md)
70
+ const [address] = assetReference.split('/');
71
+ assertContractAddress(address);
72
+ return assetReference.toLowerCase();
73
+ default:
74
+ return assetReference;
75
+ }
76
+ })();
77
+ return `${chainId}/${assetNamespace}:${assetReferenceNormalized}`;
78
+ };
79
+ // NOTE: perf critical - benchmark any changes
80
+ export const fromAssetId = (assetId) => {
81
+ const slashIdx = assetId.indexOf('/');
82
+ const chainId = assetId.substring(0, slashIdx);
83
+ const assetParts = assetId.substring(slashIdx + 1);
84
+ const { chainNamespace, chainReference } = fromChainId(chainId);
85
+ const idx = assetParts.indexOf(':');
86
+ const assetNamespace = assetParts.substring(0, idx);
87
+ const assetReference = assetParts.substring(idx + 1);
88
+ if (!isAssetIdParts(chainNamespace, chainReference, assetNamespace))
91
89
  throw new Error(`fromAssetId: invalid AssetId: ${assetId}`);
92
- }
90
+ const assetReferenceNormalized = (() => {
91
+ switch (assetNamespace) {
92
+ case 'erc20':
93
+ case 'bep20':
94
+ case 'erc721':
95
+ case 'erc1155':
96
+ case 'bep721':
97
+ case 'bep1155':
98
+ return assetReference.toLowerCase();
99
+ default:
100
+ return assetReference;
101
+ }
102
+ })();
103
+ return {
104
+ chainId,
105
+ chainNamespace: chainNamespace,
106
+ chainReference: chainReference,
107
+ assetNamespace: assetNamespace,
108
+ assetReference: assetReferenceNormalized,
109
+ };
110
+ };
111
+ // NOTE: perf critical - benchmark any changes
112
+ export const isNft = (assetId) => {
113
+ const slashIdx = assetId.indexOf('/');
114
+ const assetParts = assetId.substring(slashIdx + 1);
115
+ const idx = assetParts.indexOf(':');
116
+ const assetNamespace = assetParts.substring(0, idx);
117
+ return ['erc721', 'erc1155', 'bep721', 'bep1155'].includes(assetNamespace);
93
118
  };
94
- exports.fromAssetId = fromAssetId;
95
- exports.toCAIP19 = exports.toAssetId;
96
- exports.fromCAIP19 = exports.fromAssetId;
119
+ export const toCAIP19 = toAssetId;
120
+ export const fromCAIP19 = fromAssetId;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,336 @@
1
+ import { omit } from 'lodash';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { toChainId } from '../chainId/chainId';
4
+ import { ASSET_REFERENCE, CHAIN_NAMESPACE, CHAIN_REFERENCE } from '../constants';
5
+ import { fromAssetId, fromCAIP19, toAssetId, toCAIP19 } from './assetId';
6
+ describe('assetId', () => {
7
+ it('should have matching CAIP19 aliases', () => {
8
+ expect(toAssetId).toEqual(toCAIP19);
9
+ expect(fromAssetId).toEqual(fromCAIP19);
10
+ });
11
+ describe('toAssetId', () => {
12
+ describe('toAssetId(fromAssetId())', () => {
13
+ it.each([
14
+ ['eip155:1/slip44:60'],
15
+ ['eip155:1/erc20:0xc770eefad204b5180df6a14ee197d99d808ee52d'],
16
+ ['bip122:000000000019d6689c085ae165831e93/slip44:0'],
17
+ ['cosmos:cosmoshub-4/slip44:118'],
18
+ ['cosmos:thorchain-1/slip44:tcy'],
19
+ ])('returns an AssetId from the result of fromAssetId for %s', assetId => {
20
+ const result = fromAssetId(assetId);
21
+ expect(toAssetId(omit(result, 'chainId'))).toBe(assetId);
22
+ expect(toAssetId(omit(result, ['chainNamespace', 'chainReference']))).toBe(assetId);
23
+ });
24
+ });
25
+ it('can make eth AssetId on mainnet', () => {
26
+ const chainNamespace = CHAIN_NAMESPACE.Evm;
27
+ const chainReference = CHAIN_REFERENCE.EthereumMainnet;
28
+ const assetIdArgSuperset = {
29
+ chainNamespace,
30
+ chainReference,
31
+ assetNamespace: 'slip44',
32
+ assetReference: ASSET_REFERENCE.Ethereum,
33
+ chainId: toChainId({ chainNamespace, chainReference }),
34
+ };
35
+ const expected = 'eip155:1/slip44:60';
36
+ expect(toAssetId(omit(assetIdArgSuperset, 'chainId'))).toEqual(expected);
37
+ expect(toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toEqual(expected);
38
+ });
39
+ it('throws with invalid eth network', () => {
40
+ const chainNamespace = CHAIN_NAMESPACE.Evm;
41
+ const chainReference = CHAIN_REFERENCE.CosmosHubMainnet;
42
+ const assetIdArgSuperset = {
43
+ chainNamespace,
44
+ chainReference,
45
+ assetNamespace: 'slip44',
46
+ assetReference: ASSET_REFERENCE.Ethereum,
47
+ chainId: `${chainNamespace}:${chainReference}`,
48
+ };
49
+ expect(() => toAssetId(omit(assetIdArgSuperset, 'chainId'))).toThrow();
50
+ expect(() => toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toThrow();
51
+ });
52
+ it('throws with invalid namespace', () => {
53
+ const chainNamespace = CHAIN_NAMESPACE.Evm;
54
+ const chainReference = CHAIN_REFERENCE.EthereumMainnet;
55
+ const assetIdArgSuperset = {
56
+ chainNamespace,
57
+ chainReference,
58
+ assetNamespace: 'bad',
59
+ assetReference: ASSET_REFERENCE.Ethereum,
60
+ chainId: `${chainNamespace}:${chainReference}`,
61
+ };
62
+ expect(() => toAssetId(omit(assetIdArgSuperset, 'chainId'))).toThrow();
63
+ expect(() => toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toThrow();
64
+ });
65
+ it('can make Cosmos AssetId on CosmosHub mainnet', () => {
66
+ const chainNamespace = CHAIN_NAMESPACE.CosmosSdk;
67
+ const chainReference = CHAIN_REFERENCE.CosmosHubMainnet;
68
+ const assetIdArgSuperset = {
69
+ chainNamespace,
70
+ chainReference,
71
+ assetNamespace: 'slip44',
72
+ assetReference: ASSET_REFERENCE.Cosmos,
73
+ chainId: toChainId({ chainNamespace, chainReference }),
74
+ };
75
+ const expected = 'cosmos:cosmoshub-4/slip44:118';
76
+ expect(toAssetId(omit(assetIdArgSuperset, 'chainId'))).toEqual(expected);
77
+ expect(toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toEqual(expected);
78
+ });
79
+ it('can make an IBC AssetId on CosmosHub', () => {
80
+ const chainNamespace = CHAIN_NAMESPACE.CosmosSdk;
81
+ const chainReference = CHAIN_REFERENCE.CosmosHubMainnet;
82
+ const assetIdArgSuperset = {
83
+ chainNamespace,
84
+ chainReference,
85
+ assetNamespace: 'ibc',
86
+ assetReference: '14F9BC3E44B8A9C1BE1FB08980FAB87034C9905EF17CF2F5008FC085218811CC',
87
+ chainId: toChainId({ chainNamespace, chainReference }),
88
+ };
89
+ const expected = 'cosmos:cosmoshub-4/ibc:14F9BC3E44B8A9C1BE1FB08980FAB87034C9905EF17CF2F5008FC085218811CC';
90
+ expect(toAssetId(omit(assetIdArgSuperset, 'chainId'))).toEqual(expected);
91
+ expect(toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toEqual(expected);
92
+ });
93
+ it('throws with invalid Cosmos network', () => {
94
+ const chainNamespace = CHAIN_NAMESPACE.CosmosSdk;
95
+ const chainReference = CHAIN_REFERENCE.BitcoinMainnet;
96
+ const assetIdArgSuperset = {
97
+ chainNamespace,
98
+ chainReference,
99
+ assetNamespace: 'slip44',
100
+ assetReference: ASSET_REFERENCE.Cosmos,
101
+ chainId: `${chainNamespace}:${chainReference}`,
102
+ };
103
+ expect(() => toAssetId(omit(assetIdArgSuperset, 'chainId'))).toThrow();
104
+ expect(() => toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toThrow();
105
+ });
106
+ it('throws with invalid Cosmos slip44 reference', () => {
107
+ const chainNamespace = CHAIN_NAMESPACE.CosmosSdk;
108
+ const chainReference = CHAIN_REFERENCE.CosmosHubMainnet;
109
+ const assetIdArgSuperset = {
110
+ chainNamespace,
111
+ chainReference,
112
+ assetNamespace: 'slip44',
113
+ assetReference: 'bad',
114
+ chainId: `${chainNamespace}:${chainReference}`,
115
+ };
116
+ expect(() => toAssetId(omit(assetIdArgSuperset, 'chainId'))).toThrow();
117
+ expect(() => toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toThrow();
118
+ });
119
+ it('throws with invalid btc network', () => {
120
+ const chainNamespace = CHAIN_NAMESPACE.Utxo;
121
+ const chainReference = CHAIN_REFERENCE.EthereumMainnet;
122
+ const assetIdArgSuperset = {
123
+ chainNamespace,
124
+ chainReference,
125
+ assetNamespace: 'slip44',
126
+ assetReference: ASSET_REFERENCE.Bitcoin,
127
+ chainId: `${chainNamespace}:${chainReference}`,
128
+ };
129
+ expect(() => toAssetId(omit(assetIdArgSuperset, 'chainId'))).toThrow();
130
+ expect(() => toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toThrow();
131
+ });
132
+ it('can make FOX AssetId on mainnet', () => {
133
+ const chainNamespace = CHAIN_NAMESPACE.Evm;
134
+ const chainReference = CHAIN_REFERENCE.EthereumMainnet;
135
+ const assetIdArgSuperset = {
136
+ chainNamespace,
137
+ chainReference,
138
+ assetNamespace: 'erc20',
139
+ assetReference: '0xc770eefad204b5180df6a14ee197d99d808ee52d',
140
+ chainId: `${chainNamespace}:${chainReference}`,
141
+ };
142
+ const expected = 'eip155:1/erc20:0xc770eefad204b5180df6a14ee197d99d808ee52d';
143
+ expect(toAssetId(omit(assetIdArgSuperset, 'chainId'))).toEqual(expected);
144
+ expect(toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toEqual(expected);
145
+ });
146
+ it('should lower case ERC20 asset references', () => {
147
+ const chainNamespace = CHAIN_NAMESPACE.Evm;
148
+ const chainReference = CHAIN_REFERENCE.EthereumMainnet;
149
+ const assetIdArgSuperset = {
150
+ chainNamespace,
151
+ chainReference,
152
+ assetNamespace: 'erc20',
153
+ assetReference: '0xc770EEfAd204B5180dF6a14Ee197D99d808ee52d',
154
+ chainId: `${chainNamespace}:${chainReference}`,
155
+ };
156
+ const expected = 'eip155:1/erc20:0xc770eefad204b5180df6a14ee197d99d808ee52d';
157
+ expect(toAssetId(omit(assetIdArgSuperset, 'chainId'))).toEqual(expected);
158
+ expect(toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toEqual(expected);
159
+ });
160
+ it('should lower case ERC721 asset references', () => {
161
+ const chainNamespace = CHAIN_NAMESPACE.Evm;
162
+ const chainReference = CHAIN_REFERENCE.EthereumMainnet;
163
+ const assetIdArgSuperset = {
164
+ chainNamespace,
165
+ chainReference,
166
+ assetNamespace: 'erc721',
167
+ assetReference: '0xc770EEfAd204B5180dF6a14Ee197D99d808ee52d/12345',
168
+ chainId: `${chainNamespace}:${chainReference}`,
169
+ };
170
+ const expected = 'eip155:1/erc721:0xc770eefad204b5180df6a14ee197d99d808ee52d/12345';
171
+ expect(toAssetId(omit(assetIdArgSuperset, 'chainId'))).toEqual(expected);
172
+ expect(toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toEqual(expected);
173
+ });
174
+ it('throws with invalid assetReference length', () => {
175
+ const chainNamespace = CHAIN_NAMESPACE.Evm;
176
+ const chainReference = CHAIN_REFERENCE.EthereumMainnet;
177
+ const assetIdArgSuperset = {
178
+ chainNamespace,
179
+ chainReference,
180
+ assetNamespace: 'erc20',
181
+ assetReference: '0xfoo',
182
+ chainId: `${chainNamespace}:${chainReference}`,
183
+ };
184
+ expect(() => toAssetId(omit(assetIdArgSuperset, 'chainId'))).toThrow();
185
+ expect(() => toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toThrow();
186
+ });
187
+ it('throws with no assetReference string', () => {
188
+ const chainNamespace = CHAIN_NAMESPACE.Evm;
189
+ const chainReference = CHAIN_REFERENCE.EthereumMainnet;
190
+ const assetIdArgSuperset = {
191
+ chainNamespace,
192
+ chainReference,
193
+ assetNamespace: 'erc20',
194
+ assetReference: '',
195
+ chainId: `${chainNamespace}:${chainReference}`,
196
+ };
197
+ expect(() => toAssetId(omit(assetIdArgSuperset, 'chainId'))).toThrow();
198
+ expect(() => toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toThrow();
199
+ });
200
+ it('throws with invalid assetReference string', () => {
201
+ const chainNamespace = CHAIN_NAMESPACE.Evm;
202
+ const chainReference = CHAIN_REFERENCE.EthereumMainnet;
203
+ const assetIdArgSuperset = {
204
+ chainNamespace,
205
+ chainReference,
206
+ assetNamespace: 'erc20',
207
+ assetReference: 'gm',
208
+ chainId: `${chainNamespace}:${chainReference}`,
209
+ };
210
+ expect(() => toAssetId(omit(assetIdArgSuperset, 'chainId'))).toThrow();
211
+ expect(() => toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toThrow();
212
+ });
213
+ it('throws if no asset namespace provided', () => {
214
+ const chainNamespace = CHAIN_NAMESPACE.Evm;
215
+ const chainReference = CHAIN_REFERENCE.EthereumMainnet;
216
+ const assetIdArgSuperset = {
217
+ chainNamespace,
218
+ chainReference,
219
+ assetNamespace: '',
220
+ assetReference: '0xdef1cafe',
221
+ chainId: `${chainNamespace}:${chainReference}`,
222
+ };
223
+ expect(() => toAssetId(omit(assetIdArgSuperset, 'chainId'))).toThrow();
224
+ expect(() => toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toThrow();
225
+ });
226
+ it('can make bitcoin AssetId on mainnet', () => {
227
+ const chainNamespace = CHAIN_NAMESPACE.Utxo;
228
+ const chainReference = CHAIN_REFERENCE.BitcoinMainnet;
229
+ const assetIdArgSuperset = {
230
+ chainNamespace,
231
+ chainReference,
232
+ assetNamespace: 'slip44',
233
+ assetReference: ASSET_REFERENCE.Bitcoin,
234
+ chainId: `${chainNamespace}:${chainReference}`,
235
+ };
236
+ const expected = 'bip122:000000000019d6689c085ae165831e93/slip44:0';
237
+ expect(toAssetId(omit(assetIdArgSuperset, 'chainId'))).toEqual(expected);
238
+ expect(toAssetId(omit(assetIdArgSuperset, ['chainNamespace', 'chainReference']))).toEqual(expected);
239
+ });
240
+ });
241
+ describe('fromAssetId', () => {
242
+ describe('fromAssetId(toAssetId())', () => {
243
+ const slip44 = 'slip44';
244
+ const erc20 = 'erc20';
245
+ it.each([
246
+ [CHAIN_NAMESPACE.Utxo, CHAIN_REFERENCE.BitcoinMainnet, slip44, ASSET_REFERENCE.Bitcoin],
247
+ [CHAIN_NAMESPACE.Evm, CHAIN_REFERENCE.EthereumMainnet, slip44, ASSET_REFERENCE.Ethereum],
248
+ [
249
+ CHAIN_NAMESPACE.Evm,
250
+ CHAIN_REFERENCE.EthereumMainnet,
251
+ erc20,
252
+ '0xc770eefad204b5180df6a14ee197d99d808ee52d',
253
+ ],
254
+ [
255
+ CHAIN_NAMESPACE.CosmosSdk,
256
+ CHAIN_REFERENCE.CosmosHubMainnet,
257
+ slip44,
258
+ ASSET_REFERENCE.Cosmos,
259
+ ],
260
+ ])('returns a AssetId from the result of fromAssetId for %s', (chainNamespace, chainReference, assetNamespace, assetReference) => {
261
+ expect(fromAssetId(toAssetId({ chainNamespace, chainReference, assetNamespace, assetReference }))).toStrictEqual({
262
+ chainNamespace,
263
+ chainReference,
264
+ assetReference,
265
+ assetNamespace,
266
+ chainId: toChainId({ chainNamespace, chainReference }),
267
+ });
268
+ });
269
+ });
270
+ it('can return chain, network from eth AssetId on mainnet', () => {
271
+ const AssetId = 'eip155:1/slip44:60';
272
+ const { chainId, chainReference, chainNamespace, assetNamespace, assetReference } = fromAssetId(AssetId);
273
+ expect(chainNamespace).toEqual(CHAIN_NAMESPACE.Evm);
274
+ expect(chainReference).toEqual(CHAIN_REFERENCE.EthereumMainnet);
275
+ expect(chainId).toEqual(toChainId({ chainNamespace, chainReference }));
276
+ expect(assetNamespace).toEqual('slip44');
277
+ expect(assetReference).toEqual(ASSET_REFERENCE.Ethereum);
278
+ });
279
+ it('can return chain, network from bitcoin AssetId on mainnet', () => {
280
+ const AssetId = 'bip122:000000000019d6689c085ae165831e93/slip44:0';
281
+ const { chainId, chainReference, chainNamespace, assetNamespace, assetReference } = fromAssetId(AssetId);
282
+ expect(chainNamespace).toEqual(CHAIN_NAMESPACE.Utxo);
283
+ expect(chainReference).toEqual(CHAIN_REFERENCE.BitcoinMainnet);
284
+ expect(chainId).toEqual(toChainId({ chainNamespace, chainReference }));
285
+ expect(assetNamespace).toEqual('slip44');
286
+ expect(assetReference).toEqual(ASSET_REFERENCE.Bitcoin);
287
+ });
288
+ it('can return chainId, chainReference, chainNamespace, assetNamespace, assetReference from FOX AssetId on mainnet', () => {
289
+ const AssetId = 'eip155:1/erc20:0xc770eefad204b5180df6a14ee197d99d808ee52d';
290
+ const { chainId, chainReference, chainNamespace, assetNamespace, assetReference } = fromAssetId(AssetId);
291
+ expect(chainNamespace).toEqual(CHAIN_NAMESPACE.Evm);
292
+ expect(chainReference).toEqual(CHAIN_REFERENCE.EthereumMainnet);
293
+ expect(chainId).toEqual(toChainId({ chainNamespace, chainReference }));
294
+ expect(assetNamespace).toEqual('erc20');
295
+ expect(assetReference).toEqual('0xc770eefad204b5180df6a14ee197d99d808ee52d');
296
+ });
297
+ it('should lower case assetReference for assetNamespace ERC20', () => {
298
+ const AssetId = 'eip155:1/erc20:0xc770EEfAd204B5180dF6a14Ee197D99d808ee52d';
299
+ const { chainId, chainReference, chainNamespace, assetNamespace, assetReference } = fromAssetId(AssetId);
300
+ expect(chainNamespace).toEqual(CHAIN_NAMESPACE.Evm);
301
+ expect(chainReference).toEqual(CHAIN_REFERENCE.EthereumMainnet);
302
+ expect(chainId).toEqual(toChainId({ chainNamespace, chainReference }));
303
+ expect(assetNamespace).toEqual('erc20');
304
+ expect(assetReference).toEqual('0xc770eefad204b5180df6a14ee197d99d808ee52d');
305
+ });
306
+ it('should lower case assetReference for assetNamespace ERC721', () => {
307
+ const AssetId = 'eip155:1/erc721:0xc770EEfAd204B5180dF6a14Ee197D99d808ee52d/12345';
308
+ const { chainId, chainReference, chainNamespace, assetNamespace, assetReference } = fromAssetId(AssetId);
309
+ expect(chainNamespace).toEqual(CHAIN_NAMESPACE.Evm);
310
+ expect(chainReference).toEqual(CHAIN_REFERENCE.EthereumMainnet);
311
+ expect(chainId).toEqual(toChainId({ chainNamespace, chainReference }));
312
+ expect(assetNamespace).toEqual('erc721');
313
+ const [address, id] = assetReference.split('/');
314
+ expect(address).toEqual('0xc770eefad204b5180df6a14ee197d99d808ee52d');
315
+ expect(id).toEqual('12345');
316
+ });
317
+ it('can parse a cosmoshub native token', () => {
318
+ const AssetId = 'cosmos:cosmoshub-4/slip44:118';
319
+ const { chainId, chainReference, chainNamespace, assetNamespace, assetReference } = fromAssetId(AssetId);
320
+ expect(chainNamespace).toEqual(CHAIN_NAMESPACE.CosmosSdk);
321
+ expect(chainReference).toEqual(CHAIN_REFERENCE.CosmosHubMainnet);
322
+ expect(chainId).toEqual(toChainId({ chainNamespace, chainReference }));
323
+ expect(assetNamespace).toEqual('slip44');
324
+ expect(assetReference).toEqual(ASSET_REFERENCE.Cosmos);
325
+ });
326
+ it('errors for an invalid AssetId format', () => {
327
+ expect(() => fromAssetId('invalid')).toThrow();
328
+ });
329
+ it('errors for invalid ChainNamespace', () => {
330
+ expect(() => fromAssetId('invalid:cosmoshub-4/slip44:118')).toThrow();
331
+ });
332
+ it('errors for invalid ChainReference type', () => {
333
+ expect(() => fromAssetId('cosmos:invalid/slip44:118')).toThrow();
334
+ });
335
+ });
336
+ });
@@ -1,19 +1,20 @@
1
- import { CHAIN_NAMESPACE, CHAIN_REFERENCE } from '../constants';
2
- import { Nominal } from '../utils';
3
- export declare type ChainId = Nominal<string, 'ChainId'>;
4
- export declare type ChainNamespace = typeof CHAIN_NAMESPACE[keyof typeof CHAIN_NAMESPACE];
5
- export declare type ChainReference = typeof CHAIN_REFERENCE[keyof typeof CHAIN_REFERENCE];
6
- declare type ToChainIdArgs = {
1
+ import type { CHAIN_NAMESPACE, CHAIN_REFERENCE } from '../constants';
2
+ import type { Nominal } from '../utils';
3
+ export type ChainId = Nominal<string, 'ChainId'>;
4
+ export type ChainNamespace = (typeof CHAIN_NAMESPACE)[keyof typeof CHAIN_NAMESPACE];
5
+ export type ChainReference = (typeof CHAIN_REFERENCE)[keyof typeof CHAIN_REFERENCE];
6
+ type ToChainIdArgs = {
7
7
  chainNamespace: ChainNamespace;
8
8
  chainReference: ChainReference;
9
9
  };
10
10
  export declare const toChainId: (args: ToChainIdArgs) => ChainId;
11
- declare type FromChainIdReturn = {
11
+ export declare const fromChainId: (chainId: ChainId) => {
12
12
  chainNamespace: ChainNamespace;
13
13
  chainReference: ChainReference;
14
14
  };
15
- declare type FromChainId = (chainId: string) => FromChainIdReturn;
16
- export declare const fromChainId: FromChainId;
17
15
  export declare const toCAIP2: (args: ToChainIdArgs) => ChainId;
18
- export declare const fromCAIP2: FromChainId;
16
+ export declare const fromCAIP2: (chainId: ChainId) => {
17
+ chainNamespace: ChainNamespace;
18
+ chainReference: ChainReference;
19
+ };
19
20
  export {};
@@ -1,22 +1,20 @@
1
- "use strict";
2
1
  // https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.fromCAIP2 = exports.toCAIP2 = exports.fromChainId = exports.toChainId = void 0;
5
- const typeGuards_1 = require("../typeGuards");
6
- const toChainId = (args) => {
2
+ import { assertIsChainId } from '../typeGuards';
3
+ export const toChainId = (args) => {
7
4
  const { chainNamespace, chainReference } = args;
8
5
  const maybeChainId = `${chainNamespace}:${chainReference}`;
9
- (0, typeGuards_1.assertIsChainId)(maybeChainId);
6
+ assertIsChainId(maybeChainId);
10
7
  return maybeChainId;
11
8
  };
12
- exports.toChainId = toChainId;
13
- const fromChainId = (chainId) => {
14
- const [chainNamespace, chainReference] = chainId.split(':');
15
- (0, typeGuards_1.assertIsChainNamespace)(chainNamespace);
16
- (0, typeGuards_1.assertIsChainReference)(chainReference);
17
- (0, typeGuards_1.assertValidChainPartsPair)(chainNamespace, chainReference);
18
- return { chainNamespace, chainReference };
9
+ // NOTE: perf critical - benchmark any changes
10
+ export const fromChainId = (chainId) => {
11
+ const idx = chainId.indexOf(':');
12
+ const chainNamespace = chainId.substring(0, idx);
13
+ const chainReference = chainId.substring(idx + 1);
14
+ return {
15
+ chainNamespace: chainNamespace,
16
+ chainReference: chainReference,
17
+ };
19
18
  };
20
- exports.fromChainId = fromChainId;
21
- exports.toCAIP2 = exports.toChainId;
22
- exports.fromCAIP2 = exports.fromChainId;
19
+ export const toCAIP2 = toChainId;
20
+ export const fromCAIP2 = fromChainId;
@@ -0,0 +1 @@
1
+ export {};