Skip to content

Commit

Permalink
Merge pull request #2613 from build-5/impr/2612-token-trade-otr
Browse files Browse the repository at this point in the history
#2612 - TargetAddress on token trade otr
  • Loading branch information
adamunchained authored Oct 11, 2023
2 parents 2a0a56e + a25b21a commit 5231fcd
Show file tree
Hide file tree
Showing 30 changed files with 1,697 additions and 659 deletions.
453 changes: 300 additions & 153 deletions .github/workflows/functions_tangle-online-unit-tests_emulator.yml

Large diffs are not rendered by default.

360 changes: 201 additions & 159 deletions .github/workflows/functions_tangle-unit-tests.yml

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@
"cors": "^2.8.5",
"dayjs": "^1.11.9",
"express": "^4.18.2",
"joi": "17.10.2",
"joi": "17.11.0",
"lodash": "^4.17.21",
"rxjs": "^7.8.1",
"ws": "^8.13.0"
},
"devDependencies": {
"@types/cors": "^2.8.14",
"@types/express": "^4.17.17",
"@types/lodash": "^4.14.197",
"@types/ws": "^8.5.5",
Expand Down
2 changes: 1 addition & 1 deletion packages/functions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
"glob": "8.0.3",
"interfaces": "^0.0.3",
"is-ipfs": "8.0.1",
"joi": "17.10.2",
"joi": "17.11.0",
"js-big-decimal": "1.4.1",
"jsonwebtoken": "9.0.0",
"lodash": "4.17.21",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const tradeTokenControl = async (
params.type as TokenTradeOrderType,
params.count,
params.price,
'',
customParams?.ip as string | undefined,
);
if (tradeOrder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export const tradeMintedTokenSchema = toJoiObject<TradeTokenTangleRequest>({
.equal(TokenTradeOrderType.SELL, TokenTradeOrderType.BUY)
.required()
.description('Direction of the trade.'),
targetAddress: CommonJoi.uid(false).description(
'Funds will be sent here in case of a successfull trade.',
),
})
.description('Tangle request object to trade a token.')
.meta({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export class TangleTokenTradeService {
params.type as TokenTradeOrderType,
params.count || 0,
params.price,
params.targetAddress,
'',
[TokenStatus.BASE, TokenStatus.MINTED],
);
Expand All @@ -94,19 +95,6 @@ export class TangleTokenTradeService {
action: 'set',
});

if (params.type === TokenTradeOrderType.SELL && token?.status === TokenStatus.BASE) {
this.transactionService.createTangleCredit(
payment,
match,
{
amount: tradeOrderTransaction.payload.amount,
address: tradeOrderTransaction.payload.targetAddress,
},
tranEntry.outputId!,
);
return;
}

this.transactionService.createUnlockTransaction(
tradeOrderTransaction,
tran,
Expand All @@ -133,6 +121,7 @@ export const createTokenTradeOrder = async (
type: TokenTradeOrderType,
count: number,
price: number,
targetAddress = '',
ip = '',
acceptedTokenStatuses = ACCEPTED_TOKEN_STATUSES,
) => {
Expand All @@ -146,7 +135,13 @@ export const createTokenTradeOrder = async (
const [sourceNetwork, targetNetwork] = getSourceAndTargetNetwork(token, isSell);
const member = await build5Db().doc(`${COL.MEMBER}/${owner}`).get<Member>();
assertMemberHasValidAddress(member, sourceNetwork);
assertMemberHasValidAddress(member, targetNetwork);
if (targetAddress) {
if (!targetAddress.startsWith(targetNetwork === Network.ATOI ? 'rms' : targetNetwork)) {
throw invalidArgument(WenError.invalid_target_address);
}
} else {
assertMemberHasValidAddress(member, targetNetwork);
}

if ([TokenStatus.BASE, TokenStatus.MINTED].includes(token.status) || !isSell) {
const tradeOrderTransaction = await createTradeOrderTransaction(
Expand All @@ -156,6 +151,7 @@ export const createTokenTradeOrder = async (
isSell,
Number(count),
Number(price),
targetAddress,
);

return { tradeOrderTransaction, tradeOrder: undefined, distribution: undefined };
Expand Down Expand Up @@ -218,11 +214,12 @@ const createTradeOrderTransaction = async (
isSell: boolean,
count: number,
price: number,
tokenTradeOderTargetAddress = '',
): Promise<Transaction> => {
const wallet = await WalletService.newWallet(network);
const targetAddress = await wallet.getNewIotaAddressDetails();
const isMinted = token.status === TokenStatus.MINTED;
return {
const order: Transaction = {
type: TransactionType.ORDER,
uid: getRandomEthAddress(),
member,
Expand All @@ -245,6 +242,10 @@ const createTradeOrderTransaction = async (
},
linkedTransactions: [],
};
if (tokenTradeOderTargetAddress) {
set(order, 'payload.tokenTradeOderTargetAddress', tokenTradeOderTargetAddress);
}
return order;
};

const getAmount = async (token: Token, count: number, price: number, isSell: boolean) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '@build-5/interfaces';
import dayjs from 'dayjs';
import bigDecimal from 'js-big-decimal';
import { get, head, last } from 'lodash';
import { get, head, last, set } from 'lodash';
import { build5Db, getSnapshot } from '../../../firebase/firestore/build5Db';
import { dateToTimestamp } from '../../../utils/dateTime.utils';
import { getBoughtByMemberDiff, getTotalPublicSupply } from '../../../utils/token.utils';
Expand Down Expand Up @@ -159,6 +159,9 @@ export class TokenService {
sourceNetwork: network,
targetNetwork: token.status === TokenStatus.BASE ? getNetworkPair(network) : network,
};
if (order.payload.tokenTradeOderTargetAddress) {
set(data, 'targetAddress', order.payload.tokenTradeOderTargetAddress);
}

const ref = build5Db().doc(`${COL.TOKEN_MARKET}/${data.uid}`);
this.transactionService.push({ ref, data, action: 'set' });
Expand Down
4 changes: 2 additions & 2 deletions packages/functions/src/services/wallet/IotaWalletService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ export class IotaWallet extends Wallet {
).items;
const outputs = await this.client.getOutputs(outputIds);
let totalAmount = BigInt(0);
const totalNativeTokens: { [id: string]: bigint } = {};
const totalNativeTokens: { [id: string]: number } = {};
for (const outputResponse of outputs) {
const output = outputResponse.output;
if (output instanceof CommonOutput) {
(output as CommonOutput).getNativeTokens()?.forEach((token) => {
totalNativeTokens[token.id] = (totalNativeTokens[token.id] || BigInt(0)) + token.amount;
totalNativeTokens[token.id] = (totalNativeTokens[token.id] || 0) + Number(token.amount);
});
}
totalAmount += output.getAmount();
Expand Down
2 changes: 1 addition & 1 deletion packages/functions/src/services/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface WalletParams {
export abstract class Wallet {
public abstract getBalance: (
addressBech32: string,
) => Promise<{ amount: number; nativeTokens: { [id: string]: bigint } }>;
) => Promise<{ amount: number; nativeTokens: { [id: string]: number } }>;
public abstract getNewIotaAddressDetails: (saveMnemonic?: boolean) => Promise<AddressDetails>;
public abstract getIotaAddressDetails: (mnemonic: string) => Promise<AddressDetails>;
public abstract getAddressDetails: (bech32: string) => Promise<AddressDetails>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { getMemberTier, getTokenTradingFee } from './token-trade-order.trigger';
const createIotaPayments = async (
token: Token,
sell: TokenTradeOrder,
buy: TokenTradeOrder,
seller: Member,
buyer: Member,
count: number,
Expand All @@ -52,7 +53,7 @@ const createIotaPayments = async (
type: TransactionPayloadType.BASE_TOKEN_TRADE,
amount: count,
sourceAddress: sellOrder!.payload.targetAddress,
targetAddress: getAddress(buyer, sell.sourceNetwork!),
targetAddress: buy.targetAddress || getAddress(buyer, sell.sourceNetwork!),
previousOwnerEntity: Entity.MEMBER,
previousOwner: seller.uid,
ownerEntity: Entity.MEMBER,
Expand Down Expand Up @@ -193,7 +194,7 @@ const createSmrPayments = async (
type: TransactionPayloadType.BASE_TOKEN_TRADE,
amount: salePrice,
sourceAddress: buyOrder!.payload.targetAddress,
targetAddress: getAddress(seller, buy.sourceNetwork!),
targetAddress: sell.targetAddress || getAddress(seller, buy.sourceNetwork!),
previousOwnerEntity: Entity.MEMBER,
previousOwner: buy.owner,
ownerEntity: Entity.MEMBER,
Expand Down Expand Up @@ -247,7 +248,7 @@ export const matchBaseToken = async (
const seller = await build5Db().doc(`${COL.MEMBER}/${sell.owner}`).get<Member>();
const buyer = await build5Db().doc(`${COL.MEMBER}/${buy.owner}`).get<Member>();

const iotaPayments = await createIotaPayments(token, sell, seller!, buyer!, tokensToTrade);
const iotaPayments = await createIotaPayments(token, sell, buy, seller!, buyer!, tokensToTrade);
const smrPayments = await createSmrPayments(
token,
sell,
Expand Down
30 changes: 15 additions & 15 deletions packages/functions/src/triggers/token-trading/match-minted-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,19 @@ const createBillPaymentToSeller = async (
buyer: Member,
seller: Member,
buyOrderTran: Transaction,
sell: TokenTradeOrder,
buy: TokenTradeOrder,
salePrice: number,
) => {
const sellerAddress = getAddress(seller, token.mintingData?.network!);
const network = token.mintingData?.network!;
const sellerAddress = sell.targetAddress || getAddress(seller, network);
const output = await packBasicOutput(wallet, sellerAddress, salePrice, {});
return <Transaction>{
type: TransactionType.BILL_PAYMENT,
uid: getRandomEthAddress(),
space: token.space,
member: buyer.uid,
network: token.mintingData?.network!,
network,
payload: {
type: TransactionPayloadType.MINTED_TOKEN_TRADE,
amount: Number(output.amount),
Expand Down Expand Up @@ -123,8 +125,9 @@ const createBillPaymentWithNativeTokens = async (
sell: TokenTradeOrder,
tokensToSell: number,
): Promise<Transaction> => {
const sellerAddress = getAddress(seller, token.mintingData?.network!);
const buyerAddress = getAddress(buyer, token.mintingData?.network!);
const network = token.mintingData?.network!;
const sellerAddress = getAddress(seller, network);
const buyerAddress = buy.targetAddress || getAddress(buyer, network);
const output = await packBasicOutput(wallet, buyerAddress, 0, {
nativeTokens: [{ id: token.mintingData?.tokenId!, amount: BigInt(tokensToSell) }],
storageDepositReturnAddress: sellerAddress,
Expand All @@ -134,7 +137,7 @@ const createBillPaymentWithNativeTokens = async (
uid: getRandomEthAddress(),
space: token.space,
member: seller.uid,
network: token.mintingData?.network!,
network,
payload: {
type: TransactionPayloadType.MINTED_TOKEN_TRADE,
amount: Number(output.amount),
Expand Down Expand Up @@ -164,9 +167,8 @@ const createCreditToSeller = (
seller: Member,
sell: TokenTradeOrder,
sellOrderTran: Transaction,
) => {
const sellerAddress = getAddress(seller, token.mintingData?.network!);
return <Transaction>{
) =>
<Transaction>{
type: TransactionType.CREDIT,
uid: getRandomEthAddress(),
space: token.space,
Expand All @@ -177,7 +179,7 @@ const createCreditToSeller = (
dependsOnBillPayment: true,
amount: sellOrderTran.payload.amount,
sourceAddress: sellOrderTran.payload.targetAddress,
targetAddress: sellerAddress,
targetAddress: getAddress(seller, token.mintingData?.network!),
previousOwnerEntity: Entity.MEMBER,
previousOwner: seller.uid,
ownerEntity: Entity.MEMBER,
Expand All @@ -189,17 +191,15 @@ const createCreditToSeller = (
tokenSymbol: token.symbol,
},
};
};

const createCreditToBuyer = (
token: Token,
buyer: Member,
buy: TokenTradeOrder,
buyOrderTran: Transaction,
amount: number,
) => {
const buyerAddress = getAddress(buyer, token.mintingData?.network!);
return <Transaction>{
) =>
<Transaction>{
type: TransactionType.CREDIT,
uid: getRandomEthAddress(),
space: token.space,
Expand All @@ -210,7 +210,7 @@ const createCreditToBuyer = (
dependsOnBillPayment: true,
amount,
sourceAddress: buyOrderTran.payload.targetAddress,
targetAddress: buyerAddress,
targetAddress: getAddress(buyer, token.mintingData?.network!),
previousOwnerEntity: Entity.MEMBER,
previousOwner: buyer.uid,
ownerEntity: Entity.MEMBER,
Expand All @@ -222,7 +222,6 @@ const createCreditToBuyer = (
tokenSymbol: token.symbol,
},
};
};

export const matchMintedToken = async (
transaction: ITransaction,
Expand Down Expand Up @@ -298,6 +297,7 @@ export const matchMintedToken = async (
buyer,
seller,
buyOrderTran,
sell,
buy,
salePrice,
);
Expand Down
Loading

0 comments on commit 5231fcd

Please sign in to comment.