Skip to content

Commit 7fc9323

Browse files
Merge pull request #6325 from BitGo/WIN-5948
feat: add WORLDCHAIN token support
2 parents 7a80061 + 48cabb3 commit 7fc9323

File tree

11 files changed

+275
-2
lines changed

11 files changed

+275
-2
lines changed

modules/bitgo/src/v2/coinFactory.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ import {
195195
Vet,
196196
Wemix,
197197
World,
198+
WorldToken,
198199
Xdc,
199200
Xlm,
200201
Xrp,
@@ -439,6 +440,10 @@ export function registerCoinConstructors(coinFactory: CoinFactory, coinMap: Coin
439440
coinFactory.register(name, coinConstructor);
440441
});
441442

443+
WorldToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
444+
coinFactory.register(name, coinConstructor);
445+
});
446+
442447
SolToken.createTokenConstructors([...tokens.bitcoin.sol.tokens, ...tokens.testnet.sol.tokens]).forEach(
443448
({ name, coinConstructor }) => {
444449
coinFactory.register(name, coinConstructor);

modules/bitgo/src/v2/coins/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ import { Trx, Ttrx } from '@bitgo/sdk-coin-trx';
6363
import { StellarToken, Txlm, Xlm } from '@bitgo/sdk-coin-xlm';
6464
import { Vet, Tvet } from '@bitgo/sdk-coin-vet';
6565
import { Wemix, Twemix } from '@bitgo/sdk-coin-wemix';
66-
import { World, Tworld } from '@bitgo/sdk-coin-world';
66+
import { World, Tworld, WorldToken } from '@bitgo/sdk-coin-world';
6767
import { Xdc, Txdc } from '@bitgo/sdk-coin-xdc';
6868
import { Txrp, Xrp, XrpToken } from '@bitgo/sdk-coin-xrp';
6969
import { Txtz, Xtz } from '@bitgo/sdk-coin-xtz';
@@ -141,7 +141,7 @@ export { Txtz, Xtz };
141141
export { Tzec, Zec };
142142
export { Tzeta, Zeta };
143143
export { Wemix, Twemix };
144-
export { World, Tworld };
144+
export { World, Tworld, WorldToken };
145145
export { Zketh, Tzketh, ZkethToken };
146146

147147
import { coins } from '@bitgo/sdk-core';

modules/bitgo/test/browser/browser.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ describe('Coins', () => {
4545
CoredaoToken: 1,
4646
EvmCoin: 1,
4747
Nep141Token: 1,
48+
WorldToken: 1,
4849
};
4950
Object.keys(BitGoJS.Coin)
5051
.filter((coinName) => !excludedKeys[coinName])

modules/sdk-coin-world/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ export * from './lib';
22
export * from './world';
33
export * from './tworld';
44
export * from './register';
5+
export * from './tworld';
6+
export * from './worldToken';
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { BitGoBase } from '@bitgo/sdk-core';
22
import { World } from './world';
33
import { Tworld } from './tworld';
4+
import { WorldToken } from './worldToken';
45

56
export const register = (sdk: BitGoBase): void => {
67
sdk.register('world', World.createInstance);
78
sdk.register('tworld', Tworld.createInstance);
9+
WorldToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
10+
sdk.register(name, coinConstructor);
11+
});
812
};
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* @prettier
3+
*/
4+
import { coins, EthLikeTokenConfig } from '@bitgo/statics';
5+
import { BitGoBase, CoinConstructor, common, MPCAlgorithm, NamedCoinConstructor } from '@bitgo/sdk-core';
6+
import { CoinNames, EthLikeToken, recoveryBlockchainExplorerQuery } from '@bitgo/abstract-eth';
7+
8+
import { TransactionBuilder } from './lib';
9+
10+
export { EthLikeTokenConfig };
11+
12+
export class WorldToken extends EthLikeToken {
13+
public readonly tokenConfig: EthLikeTokenConfig;
14+
static coinNames: CoinNames = {
15+
Mainnet: 'world',
16+
Testnet: 'tworld',
17+
};
18+
constructor(bitgo: BitGoBase, tokenConfig: EthLikeTokenConfig) {
19+
super(bitgo, tokenConfig, WorldToken.coinNames);
20+
}
21+
static createTokenConstructor(config: EthLikeTokenConfig): CoinConstructor {
22+
return super.createTokenConstructor(config, WorldToken.coinNames);
23+
}
24+
25+
static createTokenConstructors(): NamedCoinConstructor[] {
26+
return super.createTokenConstructors(WorldToken.coinNames);
27+
}
28+
29+
protected getTransactionBuilder(): TransactionBuilder {
30+
return new TransactionBuilder(coins.get(this.getBaseChain()));
31+
}
32+
33+
/** @inheritDoc **/
34+
getMPCAlgorithm(): MPCAlgorithm {
35+
return 'ecdsa';
36+
}
37+
38+
/** @inheritDoc */
39+
supportsTss(): boolean {
40+
return true;
41+
}
42+
43+
/**
44+
* Make a query to World Chain explorer for information such as balance, token balance, solidity calls
45+
* @param {Object} query key-value pairs of parameters to append after /api
46+
* @returns {Promise<Object>} response World Chain explorer
47+
*/
48+
async recoveryBlockchainExplorerQuery(query: Record<string, string>): Promise<Record<string, unknown>> {
49+
const apiToken = common.Environments[this.bitgo.getEnv()].worldExplorerApiToken;
50+
const explorerUrl = common.Environments[this.bitgo.getEnv()].worldExplorerBaseUrl;
51+
return await recoveryBlockchainExplorerQuery(query, explorerUrl as string, apiToken);
52+
}
53+
54+
getFullName(): string {
55+
return 'World Token';
56+
}
57+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
2+
import { BitGoAPI } from '@bitgo/sdk-api';
3+
4+
import { WorldToken } from '../../src/worldToken';
5+
6+
describe('World Token:', function () {
7+
let bitgo: TestBitGoAPI;
8+
let worldTokenCoin;
9+
const tokenName = 'tworld:wld';
10+
11+
before(function () {
12+
bitgo = TestBitGo.decorate(BitGoAPI, { env: 'test' });
13+
WorldToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
14+
bitgo.safeRegister(name, coinConstructor);
15+
});
16+
bitgo.initializeTestVars();
17+
worldTokenCoin = bitgo.coin(tokenName);
18+
});
19+
20+
it('should return constants', function () {
21+
worldTokenCoin.getChain().should.equal('tworld:wld');
22+
worldTokenCoin.getBaseChain().should.equal('tworld');
23+
worldTokenCoin.getFullName().should.equal('World Token');
24+
worldTokenCoin.getBaseFactor().should.equal(1e18);
25+
worldTokenCoin.type.should.equal(tokenName);
26+
worldTokenCoin.name.should.equal('Worldcoin Testnet');
27+
worldTokenCoin.coin.should.equal('tworld');
28+
worldTokenCoin.network.should.equal('Testnet');
29+
worldTokenCoin.decimalPlaces.should.equal(18);
30+
});
31+
});

modules/statics/src/account.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,16 @@ export class CoredaoERC20Token extends ContractAddressDefinedToken {
483483
}
484484
}
485485

486+
/**
487+
* The World Chain network supports tokens
488+
* World Chain Tokens are ERC20 tokens
489+
*/
490+
export class WorldERC20Token extends ContractAddressDefinedToken {
491+
constructor(options: Erc20ConstructorOptions) {
492+
super(options);
493+
}
494+
}
495+
486496
/**
487497
* The Xrp network supports tokens
488498
* Xrp tokens are identified by their issuer address
@@ -2426,6 +2436,96 @@ export function tcoredaoErc20(
24262436
);
24272437
}
24282438

2439+
/**
2440+
* Factory function for WorldErc20 token instances.
2441+
*
2442+
* @param id uuid v4
2443+
* @param name unique identifier of the token
2444+
* @param fullName Complete human-readable name of the token
2445+
* @param decimalPlaces Number of decimal places this token supports (divisibility exponent)
2446+
* @param contractAddress Contract address of this token
2447+
* @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin.
2448+
* @param prefix? Optional token prefix. Defaults to empty string
2449+
* @param suffix? Optional token suffix. Defaults to token name.
2450+
* @param network? Optional token network. Defaults to World Chain mainnet network.
2451+
* @param features? Features of this coin. Defaults to the DEFAULT_FEATURES defined in `AccountCoin`
2452+
* @param primaryKeyCurve The elliptic curve for this chain/token
2453+
*/
2454+
export function worldErc20(
2455+
id: string,
2456+
name: string,
2457+
fullName: string,
2458+
decimalPlaces: number,
2459+
contractAddress: string,
2460+
asset: UnderlyingAsset,
2461+
features: CoinFeature[] = [...AccountCoin.DEFAULT_FEATURES, CoinFeature.EIP1559],
2462+
prefix = '',
2463+
suffix: string = name.toUpperCase(),
2464+
network: AccountNetwork = Networks.main.world,
2465+
primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1
2466+
) {
2467+
return Object.freeze(
2468+
new WorldERC20Token({
2469+
id,
2470+
name,
2471+
fullName,
2472+
network,
2473+
contractAddress,
2474+
prefix,
2475+
suffix,
2476+
features,
2477+
decimalPlaces,
2478+
asset,
2479+
isToken: true,
2480+
primaryKeyCurve,
2481+
baseUnit: BaseUnit.ETH,
2482+
})
2483+
);
2484+
}
2485+
2486+
/**
2487+
* Factory function for world testnet worldErc20 token instances.
2488+
*
2489+
* @param id uuid v4
2490+
* @param name unique identifier of the token
2491+
* @param fullName Complete human-readable name of the token
2492+
* @param decimalPlaces Number of decimal places this token supports (divisibility exponent)
2493+
* @param contractAddress Contract address of this token
2494+
* @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin.
2495+
* @param prefix? Optional token prefix. Defaults to empty string
2496+
* @param suffix? Optional token suffix. Defaults to token name.
2497+
* @param network? Optional token network. Defaults to the World Chain test network.
2498+
* @param features? Features of this coin. Defaults to the DEFAULT_FEATURES defined in `AccountCoin`
2499+
* @param primaryKeyCurve The elliptic curve for this chain/token
2500+
*/
2501+
export function tworldErc20(
2502+
id: string,
2503+
name: string,
2504+
fullName: string,
2505+
decimalPlaces: number,
2506+
contractAddress: string,
2507+
asset: UnderlyingAsset,
2508+
features: CoinFeature[] = AccountCoin.DEFAULT_FEATURES,
2509+
prefix = '',
2510+
suffix: string = name.toUpperCase(),
2511+
network: AccountNetwork = Networks.test.coredao,
2512+
primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1
2513+
) {
2514+
return worldErc20(
2515+
id,
2516+
name,
2517+
fullName,
2518+
decimalPlaces,
2519+
contractAddress,
2520+
asset,
2521+
features,
2522+
prefix,
2523+
suffix,
2524+
network,
2525+
primaryKeyCurve
2526+
);
2527+
}
2528+
24292529
/**
24302530
* Factory function for xrp token instances.
24312531
*

modules/statics/src/base.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2523,6 +2523,14 @@ export enum UnderlyingAsset {
25232523
// coredao testnet tokens
25242524
'tcoredao:stcore' = 'tcoredao:stcore',
25252525

2526+
//world chain mainnet tokens
2527+
'world:wld' = 'world:wld',
2528+
'world:usdc' = 'world:usdc',
2529+
2530+
//world chain testnet tokens
2531+
'tworld:wld' = 'tworld:wld',
2532+
'tworld:usdc' = 'tworld:usdc',
2533+
25262534
ERC721 = 'erc721',
25272535
ERC1155 = 'erc1155',
25282536
NONSTANDARD = 'nonstandard',

modules/statics/src/coins.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
bscToken,
1111
celoToken,
1212
coredaoErc20,
13+
worldErc20,
1314
eosToken,
1415
erc1155,
1516
erc20,
@@ -44,6 +45,7 @@ import {
4445
tsuiToken,
4546
ttronToken,
4647
txrpToken,
48+
tworldErc20,
4749
tzkethErc20,
4850
xrpToken,
4951
zkethErc20,
@@ -3216,6 +3218,38 @@ export const coins = CoinMap.fromCoins([
32163218
'0x6401f24ef7c54032f4f54e67492928973ab87650',
32173219
UnderlyingAsset['tcoredao:stcore']
32183220
),
3221+
worldErc20(
3222+
'35cadba6-2324-4ad0-b809-fbdbb59e6ce3',
3223+
'world:wld',
3224+
'Worldcoin',
3225+
18,
3226+
'0x2cfc85d8e48f8eab294be644d9e25c3030863003',
3227+
UnderlyingAsset['world:wld']
3228+
),
3229+
worldErc20(
3230+
'78aaa845-2c36-4f16-bc0f-6a4c65b43dab',
3231+
'world:usdc',
3232+
'USDC',
3233+
18,
3234+
'0x79a02482a880bce3f13e09da970dc34db4cd24d1',
3235+
UnderlyingAsset['world:usdc']
3236+
),
3237+
tworldErc20(
3238+
'c5acdc9b-d0d4-4e0c-88fe-2cc68504cf86',
3239+
'tworld:wld',
3240+
'Worldcoin Testnet',
3241+
18,
3242+
'0x8803e47fd253915f9c860837f391aa71b3e03c5a',
3243+
UnderlyingAsset['tworld:wld']
3244+
),
3245+
tworldErc20(
3246+
'd347b3ba-73ac-4f3d-bd3a-e68b7c1e4669',
3247+
'tworld:usdc',
3248+
'USDC',
3249+
18,
3250+
'0x66145f38cbac35ca6f1dfb4914df98f1614aea88',
3251+
UnderlyingAsset['tworld:usdc']
3252+
),
32193253
txrpToken(
32203254
'8ef16158-1015-4a67-b6fe-db669c18ab2b',
32213255
'txrp:tst-rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd',

0 commit comments

Comments
 (0)