Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions modules/bitgo/src/v2/coinFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
AdaTokenConfig,
AlgoTokenConfig,
TrxTokenConfig,
XrpMptTokenConfig,
XrpTokenConfig,
SuiTokenConfig,
AptTokenConfig,
Expand Down Expand Up @@ -222,6 +223,7 @@ import {
XdcToken,
Xlm,
Xrp,
XrpMptToken,
XrpToken,
Xtz,
Zec,
Expand Down Expand Up @@ -543,6 +545,10 @@ export function registerCoinConstructors(coinFactory: CoinFactory, coinMap: Coin
({ name, coinConstructor }) => coinFactory.register(name, coinConstructor)
);

XrpMptToken.createTokenConstructors([...tokens.bitcoin.xrp.mptTokens, ...tokens.testnet.xrp.mptTokens]).forEach(
({ name, coinConstructor }) => coinFactory.register(name, coinConstructor)
);

AptToken.createTokenConstructors([...tokens.bitcoin.apt.tokens, ...tokens.testnet.apt.tokens]).forEach(
({ name, coinConstructor }) => coinFactory.register(name, coinConstructor)
);
Expand Down Expand Up @@ -1065,6 +1071,9 @@ export function getTokenConstructor(tokenConfig: TokenConfig): CoinConstructor |
return PolyxToken.createTokenConstructor(tokenConfig as PolyxTokenConfig);
case 'xrp':
case 'txrp':
if ('canTransfer' in tokenConfig) {
return XrpMptToken.createTokenConstructor(tokenConfig as XrpMptTokenConfig);
}
return XrpToken.createTokenConstructor(tokenConfig as XrpTokenConfig);
case 'apt':
case 'tapt':
Expand Down
4 changes: 2 additions & 2 deletions modules/bitgo/src/v2/coins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ import { Vet, Tvet, VetToken } from '@bitgo/sdk-coin-vet';
import { Wemix, Twemix } from '@bitgo/sdk-coin-wemix';
import { World, Tworld, WorldToken } from '@bitgo/sdk-coin-world';
import { Xdc, Txdc, XdcToken } from '@bitgo/sdk-coin-xdc';
import { Txrp, Xrp, XrpToken } from '@bitgo/sdk-coin-xrp';
import { Txrp, Xrp, XrpMptToken, XrpToken } from '@bitgo/sdk-coin-xrp';
import { Txtz, Xtz } from '@bitgo/sdk-coin-xtz';
import { Tzec, Zec } from '@bitgo/sdk-coin-zec';
import { Tzeta, Zeta } from '@bitgo/sdk-coin-zeta';
Expand Down Expand Up @@ -150,7 +150,7 @@ export { Trx, Ttrx };
export { Vet, Tvet, VetToken };
export { Xdc, Txdc, XdcToken };
export { StellarToken, Txlm, Xlm };
export { Txrp, Xrp, XrpToken };
export { Txrp, Xrp, XrpMptToken, XrpToken };
export { Txtz, Xtz };
export { Tzec, Zec };
export { Tzeta, Zeta };
Expand Down
1 change: 1 addition & 0 deletions modules/bitgo/test/browser/browser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('Coins', () => {
TaoToken: 1,
PolyxToken: 1,
BeraToken: 1,
XrpMptToken: 1,
XrpToken: 1,
Rune: 1,
Trune: 1,
Expand Down
1 change: 1 addition & 0 deletions modules/sdk-coin-xrp/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './register';
export * from './txrp';
export * from './xrp';
export * from './xrpToken';
export * from './xrpMptToken';
4 changes: 4 additions & 0 deletions modules/sdk-coin-xrp/src/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ import { BitGoBase } from '@bitgo/sdk-core';
import { Txrp } from './txrp';
import { Xrp } from './xrp';
import { XrpToken } from './xrpToken';
import { XrpMptToken } from './xrpMptToken';

export const register = (sdk: BitGoBase): void => {
sdk.register('xrp', Xrp.createInstance);
sdk.register('txrp', Txrp.createInstance);
XrpToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
sdk.register(name, coinConstructor);
});
XrpMptToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
sdk.register(name, coinConstructor);
});
};
66 changes: 66 additions & 0 deletions modules/sdk-coin-xrp/src/xrpMptToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { coins, XrpMptTokenConfig, tokens } from '@bitgo/statics';
import { Xrp } from './xrp';
import { BitGoBase, CoinConstructor, NamedCoinConstructor } from '@bitgo/sdk-core';

export class XrpMptToken extends Xrp {
public readonly tokenConfig: XrpMptTokenConfig;

constructor(bitgo: BitGoBase, tokenConfig: XrpMptTokenConfig) {
const staticsCoin = tokenConfig.network === 'Mainnet' ? coins.get('xrp') : coins.get('txrp');
super(bitgo, staticsCoin);
this.tokenConfig = tokenConfig;
}

static createTokenConstructor(config: XrpMptTokenConfig): CoinConstructor {
return (bitgo: BitGoBase) => new XrpMptToken(bitgo, config);
}

static createTokenConstructors(
tokenConfigs: XrpMptTokenConfig[] = [...tokens.bitcoin.xrp.mptTokens, ...tokens.testnet.xrp.mptTokens]
): NamedCoinConstructor[] {
return tokenConfigs.map((config) => ({
name: config.type,
coinConstructor: XrpMptToken.createTokenConstructor(config),
}));
}

get name(): string {
return this.tokenConfig.name;
}

get coin(): string {
return this.tokenConfig.coin;
}

get network(): string {
return this.tokenConfig.network;
}

get contractAddress(): string {
return this.tokenConfig.contractAddress;
}

get canTransfer(): boolean {
return this.tokenConfig.canTransfer;
}

get decimalPlaces(): number {
return this.tokenConfig.decimalPlaces;
}

getChain(): string {
return this.tokenConfig.type;
}

getBaseChain(): string {
return this.coin;
}

getFullName(): string {
return 'XRP MPT Token';
}

getBaseFactor(): number {
return Math.pow(10, this.tokenConfig.decimalPlaces);
}
}
51 changes: 50 additions & 1 deletion modules/sdk-coin-xrp/test/unit/xrpToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'should';

import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
import { BitGoAPI } from '@bitgo/sdk-api';
import { XrpToken } from '../../src';
import { XrpMptToken, XrpToken } from '../../src';

describe('Xrp Tokens', function () {
let bitgo: TestBitGoAPI;
Expand Down Expand Up @@ -35,3 +35,52 @@ describe('Xrp Tokens', function () {
xrpTokenCoin.currencyCode.should.equal('524C555344000000000000000000000000000000');
});
});

describe('Xrp MPT Tokens', function () {
let bitgo: TestBitGoAPI;
let mptCoin: XrpMptToken;

before(function () {
bitgo = TestBitGo.decorate(BitGoAPI, { env: 'test' });
XrpMptToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
bitgo.safeRegister(name, coinConstructor);
});
bitgo.initializeTestVars();
mptCoin = bitgo.coin('txrp:sec0') as XrpMptToken;
});

it('should register all testnet MPT tokens', function () {
const names = XrpMptToken.createTokenConstructors().map(({ name }) => name);
names.should.containEql('txrp:sec0');
names.should.containEql('txrp:sec2');
names.should.containEql('txrp:wrapt');
names.should.containEql('txrp:ntsec');
names.should.containEql('txrp:feesec');
});

it('should return constants for txrp:sec0', function () {
mptCoin.getChain().should.equal('txrp:sec0');
mptCoin.getBaseChain().should.equal('txrp');
mptCoin.getFullName().should.equal('XRP MPT Token');
mptCoin.getBaseFactor().should.equal(1); // assetScale 0 → 10^0
mptCoin.coin.should.equal('txrp');
mptCoin.network.should.equal('Testnet');
mptCoin.decimalPlaces.should.equal(0);
mptCoin.contractAddress.should.equal('01135794225BAA3A7F9DA001AF93FB258C517F50E20DE771');
mptCoin.canTransfer.should.equal(true);
});

it('should reflect canTransfer=false for non-transferable tokens', function () {
const ntsec = bitgo.coin('txrp:ntsec') as XrpMptToken;
ntsec.canTransfer.should.equal(false);
ntsec.contractAddress.should.equal('01135791225BAA3A7F9DA001AF93FB258C517F50E20DE771');
});

it('should return correct baseFactor for tokens with non-zero assetScale', function () {
const sec2 = bitgo.coin('txrp:sec2') as XrpMptToken; // assetScale 2
sec2.getBaseFactor().should.equal(100); // 10^2

const wrapt = bitgo.coin('txrp:wrapt') as XrpMptToken; // assetScale 8
wrapt.getBaseFactor().should.equal(100000000); // 10^8
});
});
46 changes: 46 additions & 0 deletions modules/statics/src/allCoinsAndTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
ttronToken,
tvetNFTCollection,
tworldErc20,
txrpMptToken,
txrpToken,
tzkethErc20,
vetNFTCollection,
Expand Down Expand Up @@ -7553,6 +7554,51 @@ export const allCoinsAndTokens = [
'straitsx.com',
UnderlyingAsset['txrp:xsgd']
),
txrpMptToken(
'b8016d32-12d1-4bbd-b0f7-5e543557c0f7',
'txrp:sec0',
'Test Security Token 0dp',
'01135794225BAA3A7F9DA001AF93FB258C517F50E20DE771',
true,
0,
UnderlyingAsset['txrp:sec0']
),
txrpMptToken(
'5df3833f-74c4-4607-bccf-1bc061b1b092',
'txrp:sec2',
'Test Security Token 2dp',
'0113578F225BAA3A7F9DA001AF93FB258C517F50E20DE771',
true,
2,
UnderlyingAsset['txrp:sec2']
),
txrpMptToken(
'44d89e3d-4938-41bf-bc4d-a8fcd3ea34b2',
'txrp:wrapt',
'Test Wrapped Token',
'01135790225BAA3A7F9DA001AF93FB258C517F50E20DE771',
true,
8,
UnderlyingAsset['txrp:wrapt']
),
txrpMptToken(
'18c9a83b-b147-41cb-9586-e8e966948422',
'txrp:ntsec',
'Test Non-Transferable Security',
'01135791225BAA3A7F9DA001AF93FB258C517F50E20DE771',
false,
2,
UnderlyingAsset['txrp:ntsec']
),
txrpMptToken(
'2bad14c2-e6b8-41ea-a204-17ceeb501daf',
'txrp:feesec',
'Test Fee Security Token',
'01135792225BAA3A7F9DA001AF93FB258C517F50E20DE771',
true,
6,
UnderlyingAsset['txrp:feesec']
),
suiToken(
'f26941b7-1110-4aa7-a2bc-29807297a51c',
'sui:deep',
Expand Down
6 changes: 6 additions & 0 deletions modules/statics/src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3706,6 +3706,12 @@ export enum UnderlyingAsset {
'xrp:fiuaxrp' = 'xrp:fiuaxrp',
// XRP testnet tokens
'txrp:xsgd' = 'txrp:xsgd',
// XRP MPT testnet tokens
'txrp:sec0' = 'txrp:sec0',
'txrp:sec2' = 'txrp:sec2',
'txrp:wrapt' = 'txrp:wrapt',
'txrp:ntsec' = 'txrp:ntsec',
'txrp:feesec' = 'txrp:feesec',

// Sui tokens
'sui:deep' = 'sui:deep',
Expand Down
Loading