Skip to content

Commit

Permalink
Add PEN and XLM tokens to Astar portal (#1348)
Browse files Browse the repository at this point in the history
* first iteration

* add PendulumXcmRepository.ts

* fix build issues

* update PEN png

* PEN is native, so use `getNativeBalance`

* remove console.log

* use '0' instead of 'PEN'

* add XLM and EURC

* use triple '='

* update symbols and issuers

* remove EURC

* remove console

* xcPEN instead of PEN

* Add refactoring

* changing minimum amount

---------

Co-authored-by: Marcel Ebert <[email protected]>
  • Loading branch information
b-yap and ebma authored Sep 11, 2024
1 parent aeefe34 commit 8ece1cf
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/assets/img/token/PEN.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions src/assets/img/token/XLM.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/modules/xcm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,15 @@ export let xcmChainObj: XcmChainObj = {
subscan: 'https://hydration.subscan.io',
isAstarNativeToken: true,
},
[Chain.PENDULUM]: {
name: Chain.PENDULUM,
relayChain: Chain.POLKADOT,
img: require('/src/assets/img/token/PEN.svg'),
parachainId: parachainIds.PENDULUM,
endpoints: ['wss://rpc-pendulum.prd.pendulumchain.tech:443'],
subscan: 'https://pendulum.subscan.io/',
isAstarNativeToken: false,
},
};

export const xcmChains = objToArray(xcmChainObj);
Expand Down
20 changes: 20 additions & 0 deletions src/modules/xcm/tokens/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,26 @@ export const xcmToken = {
originChain: Chain.HYDRATION,
minBridgeAmount: '5',
},
{
symbol: 'xcPEN',
isNativeToken: true,
assetId: '18446744073709551634',
originAssetId: 'PEN',
logo: require('/src/assets/img/token/PEN.svg'),
isXcmCompatible: true,
originChain: Chain.PENDULUM,
minBridgeAmount: '2',
},
{
symbol: 'XLM.s',
isNativeToken: false,
assetId: '18446744073709551635',
originAssetId: 'XLM.s',
logo: require('/src/assets/img/token/XLM.svg'),
isXcmCompatible: true,
originChain: Chain.PENDULUM,
minBridgeAmount: '1',
},
],
[endpointKey.SHIDEN]: [
{
Expand Down
2 changes: 2 additions & 0 deletions src/v2/config/xcm/XcmRepositoryConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
EquilibriumXcmRepository,
UniqueXcmRepository,
HydrationXcmRepository,
PendulumXcmRepository,
} from 'src/v2/repositories/implementations';
import { Chain } from 'src/v2/models/XcmModels';
import { TypeMapping } from 'src/v2/config/types';
Expand All @@ -36,6 +37,7 @@ export const XcmRepositoryConfiguration: TypeMapping = {
[Chain.EQUILIBRIUM]: EquilibriumXcmRepository,
[Chain.UNIQUE]: UniqueXcmRepository,
[Chain.HYDRATION]: HydrationXcmRepository,
[Chain.PENDULUM]: PendulumXcmRepository,
};

export type AstarToken = 'ASTR' | 'SDN';
Expand Down
2 changes: 2 additions & 0 deletions src/v2/models/XcmModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export enum Chain {
EQUILIBRIUM = 'Equilibrium',
UNIQUE = 'Unique',
HYDRATION = 'Hydration',
PENDULUM = 'Pendulum',
}

export enum parachainIds {
Expand All @@ -43,6 +44,7 @@ export enum parachainIds {
EQUILIBRIUM = 2011,
UNIQUE = 2037,
HYDRATION = 2034,
PENDULUM = 2094,
}

export interface XcmChain {
Expand Down
1 change: 1 addition & 0 deletions src/v2/repositories/implementations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export * from './xcm/BifrostXcmRepository';
export * from './xcm/EquilibriumXcmRepository';
export * from './xcm/UniqueXcmRepository';
export * from './xcm/HydrationXcmRepository';
export * from './xcm/PendulumXcmRepository';
export * from './NftRepository';
export * from './AccountUnificationRepository';
export * from './InflationRepository';
Expand Down
106 changes: 106 additions & 0 deletions src/v2/repositories/implementations/xcm/PendulumXcmRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { BN } from '@polkadot/util';
import { XcmTokenInformation } from 'src/modules/xcm';
import { container } from 'src/v2/common';
import { ExtrinsicPayload, IApi, IApiFactory } from 'src/v2/integration';
import { Asset } from 'src/v2/models';
import { Symbols } from 'src/v2/symbols';
import { XcmRepository } from '../XcmRepository';
import { XcmChain } from 'src/v2/models/XcmModels';
import { TokensAccounts } from 'src/v2/repositories/implementations/xcm/AcalaXcmRepository';
import { decodeAddress } from '@polkadot/util-crypto';

// Mapping object for token IDs
const TOKEN_IDS: Record<string, any> = {
PEN: 'Native',
'XLM.s': { Stellar: 'StellarNative' },
};

export class PendulumXcmRepository extends XcmRepository {
constructor() {
const defaultApi = container.get<IApi>(Symbols.DefaultApi);
const apiFactory = container.get<IApiFactory>(Symbols.ApiFactory);
const registeredTokens = container.get<XcmTokenInformation[]>(Symbols.RegisteredTokens);
super(defaultApi, apiFactory, registeredTokens);
}

public async getTransferCall(
from: XcmChain,
to: XcmChain,
recipientAddress: string,
token: Asset,
amount: BN,
endpoint: string
): Promise<ExtrinsicPayload> {
if (!to.parachainId) {
throw `Parachain id for ${to.name} is not defined`;
}

const tokenData = TOKEN_IDS[token.originAssetId];
if (!tokenData) {
throw `Token name for ${token.originAssetId} is not defined`;
}

const version = 'V3';

const AccountId32 = {
id: decodeAddress(recipientAddress),
};

const destination = {
[version]: {
parents: '1',
interior: {
X2: [
{
Parachain: to.parachainId,
},
{
AccountId32,
},
],
},
},
};

const destWeight = { Unlimited: null };

return await this.buildTxCall(
from,
endpoint,
'xTokens',
'transfer',
tokenData,
amount,
destination,
destWeight
);
}

public async getTokenBalance(
address: string,
chain: XcmChain,
token: Asset,
isNativeToken: boolean,
endpoint: string
): Promise<string> {
const api = await this.apiFactory.get(endpoint);

try {
if (isNativeToken) {
const nativeBalance = await this.getNativeBalance(address, chain, endpoint);
return nativeBalance.toString();
}

const currencyId = TOKEN_IDS[token.originAssetId];
if (!currencyId) {
console.error(`Token name for ${token.originAssetId} is not defined`);
return '0';
}
const bal = await api.query.tokens.accounts<TokensAccounts>(address, currencyId);
return bal.free.toString();
} catch (e) {
console.error(e);
return '0';
}
}
}

0 comments on commit 8ece1cf

Please sign in to comment.