@vultisig/core-chain 2.29.0 → 2.29.1
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.
- package/CHANGELOG.md +27 -0
- package/dist/coin/token/metadata/chains.d.ts +1 -1
- package/dist/coin/token/metadata/chains.d.ts.map +1 -1
- package/dist/coin/token/metadata/chains.js +1 -0
- package/dist/coin/token/metadata/chains.js.map +1 -1
- package/dist/coin/token/metadata/index.d.ts.map +1 -1
- package/dist/coin/token/metadata/index.js +2 -0
- package/dist/coin/token/metadata/index.js.map +1 -1
- package/dist/coin/token/metadata/resolvers/ripple.d.ts +17 -0
- package/dist/coin/token/metadata/resolvers/ripple.d.ts.map +1 -0
- package/dist/coin/token/metadata/resolvers/ripple.js +44 -0
- package/dist/coin/token/metadata/resolvers/ripple.js.map +1 -0
- package/dist/utils/isValidTokenId.d.ts +11 -0
- package/dist/utils/isValidTokenId.d.ts.map +1 -1
- package/dist/utils/isValidTokenId.js +31 -2
- package/dist/utils/isValidTokenId.js.map +1 -1
- package/package.json +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @vultisig/core-chain
|
|
2
2
|
|
|
3
|
+
## 2.29.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1568](https://github.com/vultisig/vultisig-sdk/pull/1568) [`859ab28`](https://github.com/vultisig/vultisig-sdk/commit/859ab287d3574c508b4abce5950e8e42c17f8198) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - feat(ripple): add XRPL issued-currency (custom token) support
|
|
8
|
+
|
|
9
|
+
XRPL issued currencies (trust-line tokens / IOUs) had no token metadata resolver,
|
|
10
|
+
so custom tokens could not be added on Ripple. Adds `getRippleTokenMetadata` and
|
|
11
|
+
registers Ripple in `chainsWithTokenMetadataDiscovery`. Unlike EVM/Tron there is no
|
|
12
|
+
on-ledger metadata call: XRPL exposes no per-token decimal metadata — so the SDK
|
|
13
|
+
applies its fixed issued-currency decimal policy (`rippleIssuedCurrencyDecimals`) —
|
|
14
|
+
and the ticker is derived from the currency code, so the resolver fetches nothing.
|
|
15
|
+
Curated tokens
|
|
16
|
+
(RLUSD) get their logo and price provider merged in; an arbitrary token gets neither
|
|
17
|
+
rather than borrowing a known token's identity, since two issuers can share a ticker
|
|
18
|
+
on XRPL.
|
|
19
|
+
|
|
20
|
+
`isValidTokenId` now also accepts a human ticker (`SOLO`, `RLUSD`) wherever an
|
|
21
|
+
on-ledger currency code is accepted — the form shown on explorers like xrpscan — and
|
|
22
|
+
a new `normalizeTokenId` canonicalises a pasted id to the on-ledger form.
|
|
23
|
+
|
|
24
|
+
`BalanceService.addToken`/`removeToken` normalise the token id (and its matching
|
|
25
|
+
`contractAddress`) before it enters persisted state, so a manually added
|
|
26
|
+
`RLUSD.<issuer>` collapses onto the canonical `524C…<issuer>` that ledger discovery
|
|
27
|
+
stores instead of being kept as a second, distinct token. A no-op for chains whose
|
|
28
|
+
ids are already canonical.
|
|
29
|
+
|
|
3
30
|
## 2.29.0
|
|
4
31
|
|
|
5
32
|
### Minor Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DeriveChainKind } from '@vultisig/core-chain/ChainKind';
|
|
2
2
|
import { OtherChain } from '../../../Chain.js';
|
|
3
|
-
export declare const chainsWithTokenMetadataDiscovery: readonly ("Arbitrum" | "Base" | "Blast" | "Optimism" | "Zksync" | "Mantle" | "Avalanche" | "CronosChain" | "BSC" | "Ethereum" | "Polygon" | "Hyperliquid" | "Sei" | "Cosmos" | "Osmosis" | "Dydx" | "Kujira" | "Terra" | "TerraClassic" | "Noble" | "Akash" | "THORChain" | "MayaChain" | OtherChain.Sui | OtherChain.Solana | OtherChain.Ton | OtherChain.Tron | OtherChain.Cardano)[];
|
|
3
|
+
export declare const chainsWithTokenMetadataDiscovery: readonly ("Arbitrum" | "Base" | "Blast" | "Optimism" | "Zksync" | "Mantle" | "Avalanche" | "CronosChain" | "BSC" | "Ethereum" | "Polygon" | "Hyperliquid" | "Sei" | "Cosmos" | "Osmosis" | "Dydx" | "Kujira" | "Terra" | "TerraClassic" | "Noble" | "Akash" | "THORChain" | "MayaChain" | OtherChain.Sui | OtherChain.Solana | OtherChain.Ton | OtherChain.Ripple | OtherChain.Tron | OtherChain.Cardano)[];
|
|
4
4
|
export type ChainWithTokenMetadataDiscovery = (typeof chainsWithTokenMetadataDiscovery)[number];
|
|
5
5
|
export type ChainKindWithTokenMetadataDiscovery = DeriveChainKind<ChainWithTokenMetadataDiscovery>;
|
|
6
6
|
//# sourceMappingURL=chains.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/token/metadata/chains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAEhE,OAAO,EAAyB,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAElE,eAAO,MAAM,gCAAgC,
|
|
1
|
+
{"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/token/metadata/chains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAEhE,OAAO,EAAyB,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAElE,eAAO,MAAM,gCAAgC,6YASnC,CAAA;AAEV,MAAM,MAAM,+BAA+B,GAAG,CAAC,OAAO,gCAAgC,CAAC,CAAC,MAAM,CAAC,CAAA;AAE/F,MAAM,MAAM,mCAAmC,GAAG,eAAe,CAAC,+BAA+B,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chains.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/token/metadata/chains.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAElE,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC9C,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAC1B,UAAU,CAAC,MAAM;IACjB,UAAU,CAAC,GAAG;IACd,UAAU,CAAC,IAAI;IACf,UAAU,CAAC,OAAO;IAClB,UAAU,CAAC,GAAG;IACd,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;CACrB,CAAA"}
|
|
1
|
+
{"version":3,"file":"chains.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/token/metadata/chains.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAElE,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC9C,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAC1B,UAAU,CAAC,MAAM;IACjB,UAAU,CAAC,GAAG;IACd,UAAU,CAAC,IAAI;IACf,UAAU,CAAC,OAAO;IAClB,UAAU,CAAC,GAAG;IACd,UAAU,CAAC,MAAM;IACjB,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;CACrB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/token/metadata/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/token/metadata/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAqBlD,eAAO,MAAM,gBAAgB,EAAE,qBAM9B,CAAA"}
|
|
@@ -2,6 +2,7 @@ import { getChainKind } from '@vultisig/core-chain/ChainKind';
|
|
|
2
2
|
import { getCardanoTokenMetadata } from './resolvers/cardano.js';
|
|
3
3
|
import { getCosmosTokenMetadata } from './resolvers/cosmos.js';
|
|
4
4
|
import { getEvmTokenMetadata } from './resolvers/evm.js';
|
|
5
|
+
import { getRippleTokenMetadata } from './resolvers/ripple.js';
|
|
5
6
|
import { getSolanaTokenMetadata } from './resolvers/solana.js';
|
|
6
7
|
import { getSuiTokenMetadata } from './resolvers/sui.js';
|
|
7
8
|
import { getTonTokenMetadata } from './resolvers/ton.js';
|
|
@@ -14,6 +15,7 @@ const resolvers = {
|
|
|
14
15
|
tron: getTronTokenMetadata,
|
|
15
16
|
cardano: getCardanoTokenMetadata,
|
|
16
17
|
sui: getSuiTokenMetadata,
|
|
18
|
+
ripple: getRippleTokenMetadata,
|
|
17
19
|
};
|
|
18
20
|
export const getTokenMetadata = async (input) => {
|
|
19
21
|
const chainKind = getChainKind(input.chain);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/token/metadata/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAI7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAEvD,MAAM,SAAS,GAA4E;IACzF,GAAG,EAAE,mBAAmB;IACxB,MAAM,EAAE,sBAAsB;IAC9B,MAAM,EAAE,sBAAsB;IAC9B,GAAG,EAAE,mBAAmB;IACxB,IAAI,EAAE,oBAAoB;IAC1B,OAAO,EAAE,uBAAuB;IAChC,GAAG,EAAE,mBAAmB;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/token/metadata/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAI7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAEvD,MAAM,SAAS,GAA4E;IACzF,GAAG,EAAE,mBAAmB;IACxB,MAAM,EAAE,sBAAsB;IAC9B,MAAM,EAAE,sBAAsB;IAC9B,GAAG,EAAE,mBAAmB;IACxB,IAAI,EAAE,oBAAoB;IAC1B,OAAO,EAAE,uBAAuB;IAChC,GAAG,EAAE,mBAAmB;IACxB,MAAM,EAAE,sBAAsB;CAC/B,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAA0B,KAAK,EAAC,KAAK,EAAC,EAAE;IACnE,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAE3C,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;IAErC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAA;AACxB,CAAC,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { OtherChain } from '@vultisig/core-chain/Chain';
|
|
2
|
+
import { TokenMetadataResolver } from '../resolver.js';
|
|
3
|
+
/**
|
|
4
|
+
* Metadata for a custom XRPL issued currency identified by a `currency.issuer`
|
|
5
|
+
* token id.
|
|
6
|
+
*
|
|
7
|
+
* Unlike EVM/Tron tokens, XRPL issued currencies expose no on-ledger metadata
|
|
8
|
+
* call: issued amounts carry no fixed on-chain decimal count (we model them at
|
|
9
|
+
* {@link rippleIssuedCurrencyDecimals}) and the ticker is derived from the
|
|
10
|
+
* currency code itself, so nothing is fetched. When the token is one we curate,
|
|
11
|
+
* its logo and price provider are merged in; an arbitrary token gets neither, so
|
|
12
|
+
* it renders with a generic icon and no price rather than borrowing a known
|
|
13
|
+
* token's identity — two different issuers can share a ticker on XRPL, so the
|
|
14
|
+
* issuer (encoded in the id) is what actually distinguishes them.
|
|
15
|
+
*/
|
|
16
|
+
export declare const getRippleTokenMetadata: TokenMetadataResolver<OtherChain.Ripple>;
|
|
17
|
+
//# sourceMappingURL=ripple.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/coin/token/metadata/resolvers/ripple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AASvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAiBnD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,EAAE,qBAAqB,CAAC,UAAU,CAAC,MAAM,CAqB3E,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { parseRippleTokenId, rippleIssuedCurrencyDecimals, rippleKnownIssuedTokens, rippleTokenId, } from '@vultisig/core-chain/chains/ripple/issuedCurrency';
|
|
2
|
+
import { areEqualCoins } from '@vultisig/core-chain/coin/Coin';
|
|
3
|
+
/**
|
|
4
|
+
* Human-readable ticker for an XRPL issued currency. Standard 3-character codes
|
|
5
|
+
* (`USD`) are already tickers; the 160-bit hex form encodes ASCII right-padded
|
|
6
|
+
* with zeros, so decoding it recovers the ticker a user recognises (e.g. `RLUSD`).
|
|
7
|
+
*/
|
|
8
|
+
const toIssuedCurrencyTicker = (currency) => {
|
|
9
|
+
if (currency.length !== 40) {
|
|
10
|
+
return currency;
|
|
11
|
+
}
|
|
12
|
+
const ascii = Buffer.from(currency, 'hex').toString('ascii').replace(/\0+$/, '');
|
|
13
|
+
return /^[\x20-\x7e]+$/.test(ascii) ? ascii : currency;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Metadata for a custom XRPL issued currency identified by a `currency.issuer`
|
|
17
|
+
* token id.
|
|
18
|
+
*
|
|
19
|
+
* Unlike EVM/Tron tokens, XRPL issued currencies expose no on-ledger metadata
|
|
20
|
+
* call: issued amounts carry no fixed on-chain decimal count (we model them at
|
|
21
|
+
* {@link rippleIssuedCurrencyDecimals}) and the ticker is derived from the
|
|
22
|
+
* currency code itself, so nothing is fetched. When the token is one we curate,
|
|
23
|
+
* its logo and price provider are merged in; an arbitrary token gets neither, so
|
|
24
|
+
* it renders with a generic icon and no price rather than borrowing a known
|
|
25
|
+
* token's identity — two different issuers can share a ticker on XRPL, so the
|
|
26
|
+
* issuer (encoded in the id) is what actually distinguishes them.
|
|
27
|
+
*/
|
|
28
|
+
export const getRippleTokenMetadata = async ({ id, chain }) => {
|
|
29
|
+
const { currency, issuer } = parseRippleTokenId(id);
|
|
30
|
+
const metadata = {
|
|
31
|
+
ticker: toIssuedCurrencyTicker(currency),
|
|
32
|
+
decimals: rippleIssuedCurrencyDecimals,
|
|
33
|
+
};
|
|
34
|
+
const knownToken = rippleKnownIssuedTokens.find(token => areEqualCoins(token, { chain, id: rippleTokenId({ currency, issuer }) }));
|
|
35
|
+
if (!knownToken) {
|
|
36
|
+
return metadata;
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
...metadata,
|
|
40
|
+
logo: knownToken.logo,
|
|
41
|
+
priceProviderId: knownToken.priceProviderId,
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=ripple.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ripple.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/coin/token/metadata/resolvers/ripple.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC5B,uBAAuB,EACvB,aAAa,GACd,MAAM,mDAAmD,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAgB,MAAM,gCAAgC,CAAA;AAI5E;;;;GAIG;AACH,MAAM,sBAAsB,GAAG,CAAC,QAAgB,EAAU,EAAE;IAC1D,IAAI,QAAQ,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAEhF,OAAO,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAA;AACxD,CAAC,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAA6C,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;IACtG,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAA;IAEnD,MAAM,QAAQ,GAAiB;QAC7B,MAAM,EAAE,sBAAsB,CAAC,QAAQ,CAAC;QACxC,QAAQ,EAAE,4BAA4B;KACvC,CAAA;IAED,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACtD,aAAa,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CACzE,CAAA;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO;QACL,GAAG,QAAQ;QACX,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,eAAe,EAAE,UAAU,CAAC,eAAe;KAC5C,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -15,5 +15,16 @@ type Input = {
|
|
|
15
15
|
* are identified by a composite `currency.issuer` id and validated as such.
|
|
16
16
|
*/
|
|
17
17
|
export declare const isValidTokenId: ({ chain, id, walletCore }: Input) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Canonical form of a custom token id, for storage and equality.
|
|
20
|
+
*
|
|
21
|
+
* Only XRPL needs normalising: a token may be entered by its human ticker
|
|
22
|
+
* (`SOLO.rsoLo…`, as shown on explorers) or by its on-ledger currency code, and
|
|
23
|
+
* both must resolve to the same id so a manually added token dedupes against the
|
|
24
|
+
* same token discovered from the ledger — which always uses the on-ledger code.
|
|
25
|
+
* `rippleTokenId` re-encodes the currency to that canonical form. For every other
|
|
26
|
+
* chain the id is already canonical and returned unchanged.
|
|
27
|
+
*/
|
|
28
|
+
export declare const normalizeTokenId: ({ chain, id }: Pick<Input, "chain" | "id">) => string;
|
|
18
29
|
export {};
|
|
19
30
|
//# sourceMappingURL=isValidTokenId.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isValidTokenId.d.ts","sourceRoot":"","sources":["../../../../../packages/core/chain/utils/isValidTokenId.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"isValidTokenId.d.ts","sourceRoot":"","sources":["../../../../../packages/core/chain/utils/isValidTokenId.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAWlD,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,KAAK,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,2BAA2B,KAAK,YA0B9D,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAAI,eAAe,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC,KAAG,MAW7E,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isValidStructTag } from '@mysten/sui/utils';
|
|
2
2
|
import { Chain } from '@vultisig/core-chain/Chain';
|
|
3
|
-
import { isValidXrplCurrencyCode, parseRippleTokenId } from '@vultisig/core-chain/chains/ripple/issuedCurrency';
|
|
3
|
+
import { isValidXrplCurrencyCode, parseRippleTokenId, rippleTokenId, toXrplCurrencyCode, } from '@vultisig/core-chain/chains/ripple/issuedCurrency';
|
|
4
4
|
import { attempt } from '@vultisig/lib-utils/attempt';
|
|
5
5
|
import { isValidAddress } from './isValidAddress.js';
|
|
6
6
|
/**
|
|
@@ -22,8 +22,37 @@ export const isValidTokenId = ({ chain, id, walletCore }) => {
|
|
|
22
22
|
return false;
|
|
23
23
|
}
|
|
24
24
|
const { currency, issuer } = parsed.data;
|
|
25
|
-
|
|
25
|
+
// Accept either an on-ledger currency code (`USD`, or the 40-char hex form)
|
|
26
|
+
// or a human ticker (`SOLO`, `RLUSD`) — the latter is how tokens are
|
|
27
|
+
// referenced on explorers like xrpscan. `toXrplCurrencyCode` normalises a
|
|
28
|
+
// ticker to its on-ledger code; anything it cannot encode (e.g. a name
|
|
29
|
+
// longer than 20 bytes) is rejected.
|
|
30
|
+
const currencyCode = attempt(() => toXrplCurrencyCode(currency));
|
|
31
|
+
if ('error' in currencyCode) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return isValidXrplCurrencyCode(currencyCode.data) && isValidAddress({ chain, address: issuer, walletCore });
|
|
26
35
|
}
|
|
27
36
|
return isValidAddress({ chain, address: id, walletCore });
|
|
28
37
|
};
|
|
38
|
+
/**
|
|
39
|
+
* Canonical form of a custom token id, for storage and equality.
|
|
40
|
+
*
|
|
41
|
+
* Only XRPL needs normalising: a token may be entered by its human ticker
|
|
42
|
+
* (`SOLO.rsoLo…`, as shown on explorers) or by its on-ledger currency code, and
|
|
43
|
+
* both must resolve to the same id so a manually added token dedupes against the
|
|
44
|
+
* same token discovered from the ledger — which always uses the on-ledger code.
|
|
45
|
+
* `rippleTokenId` re-encodes the currency to that canonical form. For every other
|
|
46
|
+
* chain the id is already canonical and returned unchanged.
|
|
47
|
+
*/
|
|
48
|
+
export const normalizeTokenId = ({ chain, id }) => {
|
|
49
|
+
if (chain !== Chain.Ripple) {
|
|
50
|
+
return id;
|
|
51
|
+
}
|
|
52
|
+
const canonical = attempt(() => rippleTokenId(parseRippleTokenId(id.trim())));
|
|
53
|
+
if ('error' in canonical) {
|
|
54
|
+
return id;
|
|
55
|
+
}
|
|
56
|
+
return canonical.data;
|
|
57
|
+
};
|
|
29
58
|
//# sourceMappingURL=isValidTokenId.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isValidTokenId.js","sourceRoot":"","sources":["../../../../../packages/core/chain/utils/isValidTokenId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEpD,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAClD,OAAO,
|
|
1
|
+
{"version":3,"file":"isValidTokenId.js","sourceRoot":"","sources":["../../../../../packages/core/chain/utils/isValidTokenId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEpD,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAClD,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,aAAa,EACb,kBAAkB,GACnB,MAAM,mDAAmD,CAAA;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAQjD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAS,EAAE,EAAE;IACjE,IAAI,KAAK,KAAK,KAAK,CAAC,GAAG,EAAE,CAAC;QACxB,OAAO,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAA;IACpC,CAAC;IAED,IAAI,KAAK,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QAC3D,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;YACtB,OAAO,KAAK,CAAA;QACd,CAAC;QACD,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAA;QAExC,4EAA4E;QAC5E,qEAAqE;QACrE,0EAA0E;QAC1E,uEAAuE;QACvE,qCAAqC;QACrC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAA;QAChE,IAAI,OAAO,IAAI,YAAY,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAA;QACd,CAAC;QAED,OAAO,uBAAuB,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAA;IAC7G,CAAC;IAED,OAAO,cAAc,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,CAAA;AAC3D,CAAC,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,EAA+B,EAAU,EAAE;IACrF,IAAI,KAAK,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC7E,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,CAAA;IACX,CAAC;IAED,OAAO,SAAS,CAAC,IAAI,CAAA;AACvB,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vultisig/core-chain",
|
|
3
|
-
"version": "2.29.
|
|
3
|
+
"version": "2.29.1",
|
|
4
4
|
"description": "Blockchain chain logic shared across Vultisig clients",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -1245,6 +1245,11 @@
|
|
|
1245
1245
|
"import": "./dist/coin/token/metadata/resolvers/evm.js",
|
|
1246
1246
|
"default": "./dist/coin/token/metadata/resolvers/evm.js"
|
|
1247
1247
|
},
|
|
1248
|
+
"./coin/token/metadata/resolvers/ripple": {
|
|
1249
|
+
"types": "./dist/coin/token/metadata/resolvers/ripple.d.ts",
|
|
1250
|
+
"import": "./dist/coin/token/metadata/resolvers/ripple.js",
|
|
1251
|
+
"default": "./dist/coin/token/metadata/resolvers/ripple.js"
|
|
1252
|
+
},
|
|
1248
1253
|
"./coin/token/metadata/resolvers/solana": {
|
|
1249
1254
|
"types": "./dist/coin/token/metadata/resolvers/solana.d.ts",
|
|
1250
1255
|
"import": "./dist/coin/token/metadata/resolvers/solana.js",
|