Skip to content

Commit

Permalink
Support Extra Currency via Ton Connect
Browse files Browse the repository at this point in the history
  • Loading branch information
KuznetsovNikita committed Jan 16, 2025
1 parent 7691efd commit e99aeca
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 50 deletions.
3 changes: 2 additions & 1 deletion apps/extension/src/provider/tonconnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export const getDeviceInfo = (): DeviceInfo => {
'SendTransaction',
{
name: 'SendTransaction',
maxMessages: 4
maxMessages: 4,
extraCurrenciesSupported: true
}
]
};
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/entries/tonConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface TonConnectTransactionPayloadMessage {
amount: string | number;
payload?: string; // base64 cell
stateInit?: string; // base64 cell
extra_currencies?: [{ id: number; value: string }];
}

export type TonConnectAccount = {
Expand Down Expand Up @@ -169,6 +170,7 @@ export enum SEND_TRANSACTION_ERROR_CODES {
export type SendTransactionFeature = {
name: 'SendTransaction';
maxMessages: number;
extraCurrenciesSupported?: boolean;
};

export type SendTransactionFeatureDeprecated = 'SendTransaction';
Expand Down
70 changes: 70 additions & 0 deletions packages/core/src/service/ton-blockchain/encoder/encoder-base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Address } from '@ton/core/dist/address/Address';
import { Cell } from '@ton/core/dist/boc/Cell';
import { Dictionary } from '@ton/core/dist/dict/Dictionary';
import type { CurrencyCollection } from '@ton/core/dist/types/CurrencyCollection';
import type { MessageRelaxed } from '@ton/core/dist/types/MessageRelaxed';
import type { StateInit } from '@ton/core/dist/types/StateInit';
import BigNumber from 'bignumber.js';

export abstract class EncoderBase {
private getOtherDict = () => {
return Dictionary.empty(Dictionary.Keys.Uint(32), Dictionary.Values.BigVarUint(5));
};

protected currencyValue(src: {
amount: string | number;
extraCurrencies:
| {
id: number;
value: string;
}[]
| undefined;
}): CurrencyCollection {
const coins = BigInt(src.amount);

if (!src.extraCurrencies) {
return { coins };
}

const other = this.getOtherDict();

for (let extra of src.extraCurrencies) {
other.set(extra.id, BigInt(extra.value));
}

return { coins, other };
}

protected extraCurrencyValue(src: { id: number; weiAmount: BigNumber }): CurrencyCollection {
const other = this.getOtherDict();

other.set(src.id, BigInt(src.weiAmount.toFixed(0)));

return { coins: BigInt('0'), other };
}

protected internalMessage(src: {
to: Address;
value: CurrencyCollection;
bounce: boolean;
init?: StateInit;
body?: Cell;
}): MessageRelaxed {
return {
info: {
type: 'internal',
dest: src.to,
value: src.value,
bounce: src.bounce,
ihrDisabled: true,
bounced: false,
ihrFee: 0n,
forwardFee: 0n,
createdAt: 0,
createdLt: 0n
},
init: src.init ?? undefined,
body: src.body ?? Cell.EMPTY
};
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import {
Address,
Cell,
CurrencyCollection,
Dictionary,
MessageRelaxed,
SendMode,
StateInit
} from '@ton/core';
import { Address, SendMode } from '@ton/core';
import { userInputAddressIsBounceable } from '../utils';
import BigNumber from 'bignumber.js';
import { APIConfig } from '../../../entries/apis';
import { MessagePayloadParam, serializePayload, WalletOutgoingMessage } from './types';
import { EncoderBase } from './encoder-base';

export class ExtraCurrencyEncoder {
constructor(private readonly api: APIConfig, private readonly _walletAddress: string) {}
export class ExtraCurrencyEncoder extends EncoderBase {
constructor(private readonly api: APIConfig, private readonly _walletAddress: string) {
super();
}

encodeTransfer = async (
transfer:
Expand All @@ -38,39 +33,6 @@ export class ExtraCurrencyEncoder {
}
};

private extraCurrencyValue(src: { id: number; weiAmount: BigNumber }): CurrencyCollection {
const other = Dictionary.empty(Dictionary.Keys.Uint(32), Dictionary.Values.BigVarUint(5));

other.set(src.id, BigInt(src.weiAmount.toFixed(0)));

return { coins: BigInt('0'), other };
}

private internalMessage(src: {
to: Address;
value: CurrencyCollection;
bounce: boolean;
init?: StateInit;
body?: Cell;
}): MessageRelaxed {
return {
info: {
type: 'internal',
dest: src.to,
value: src.value,
bounce: src.bounce,
ihrDisabled: true,
bounced: false,
ihrFee: 0n,
forwardFee: 0n,
createdAt: 0,
createdLt: 0n
},
init: src.init ?? undefined,
body: src.body ?? Cell.EMPTY
};
}

private encodeSingleTransfer = async ({
id,
to,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import {
TON_CONNECT_MSG_VARIANTS_ID,
TonConnectTransactionPayload
} from '../../../entries/tonConnect';
import { EncoderBase } from './encoder-base';

export class TonConnectEncoder {
constructor(private readonly api: APIConfig, private readonly walletAddress: string) {}
export class TonConnectEncoder extends EncoderBase {
constructor(private readonly api: APIConfig, private readonly walletAddress: string) {
super();
}

encodeTransfer = async (
transfer: TonConnectTransactionPayload & {
Expand All @@ -30,10 +33,13 @@ export class TonConnectEncoder {
sendMode: SendMode.PAY_GAS_SEPARATELY + SendMode.IGNORE_ERRORS,
messages: await Promise.all(
messages.map(async item =>
internal({
this.internalMessage({
to: Address.parse(item.address),
bounce: await tonConnectAddressIsBounceable(this.api, item.address),
value: BigInt(item.amount),
value: this.currencyValue({
amount: item.amount,
extraCurrencies: item.extra_currencies
}),
init: toStateInit(item.stateInit),
body: item.payload ? Cell.fromBase64(item.payload) : undefined
})
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/service/tonConnect/connectService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ export const getDeviceInfo = (appVersion: string, maxMessages: number): DeviceIn
'SendTransaction',
{
name: 'SendTransaction',
maxMessages: maxMessages
maxMessages: maxMessages,
extraCurrenciesSupported: true
}
]
};
Expand Down

0 comments on commit e99aeca

Please sign in to comment.