> For the complete documentation index, see [llms.txt](https://smartscenarios.pirichain.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://smartscenarios.pirichain.com/psce-functions/examples/deposit-withdraw-from-foreign-chain-bsc-and-add-order-buy-and-sell-token-just-a-277-code-lines.md).

# Deposit/Withdraw from Foreign Chain (BSC) and Add Order , Buy and Sell Token, Just a 277 Code Lines!

Below sample explained how to build a simple exchange operation using with PSce

The provided code is an example of a trading and order management system designed to operate on the **Pirichain Smart Scenario** platform. It handles the swap of **BNB** and **PIRI coins**, and includes functions for liquidity management, placing and removing orders, and checking wallet balances.

#### Key Features

* **Transaction Initialization and Status Check:**\
  The `swapInitialize` function initializes the order books (asks and bids) and price data for a specific trading pair (`BNB_PIRI`).
* **Wallet Balance Check:**\
  Functions like `checkMyBNBDeposit` and `depositToken` check the balances of BNB and PIRI tokens in the user’s wallet and, if sufficient, add liquidity to the pool.
* **Wallet Blocking:**\
  The `blockWallet` and `unBlockWallet` functions allow the blocking and unblocking of wallet addresses based on specific conditions.
* **Buy/Sell Orders:**\
  The `buyToken` and `sellToken` functions search for orders with a given timestamp (ask or bid), check if the user has enough balance, and if so, execute the buy or sell order.
* **Order Management:**\
  Users can create and remove buy (`addBid`) and sell (`addAsk`) orders. These functions also handle order removal (`removeMyBid`, `removeMyAsk`).
* **Withdrawal of Liquidity:**\
  The `withdrawBnbWallet` and `withdrawToken` functions allow users to withdraw their BNB or PIRI token balances from the platform to their own wallets.

#### Usage

* **Liquidity Management in Exchanges:**\
  This system can be applied in decentralized exchanges (DEX) or liquidity pools to manage the liquidity for BNB and PIRI tokens.
* **Wallet Status and Security:**\
  Security mechanisms, such as blocking wallets and suspending transactions, are integrated into the system.

#### Example Use Cases

1. **Initializing Trading for a BNB and PIRI Pair:**\
   Users can call the `swapInitialize` function to set up the liquidity and order books for BNB and PIRI coins.
2. **Placing and Removing Orders:**\
   Users can place bids and asks at a specific level (`level`) and quantity (`quantity`), or remove them if needed.
3. **Withdrawing Liquidity:**\
   Users can withdraw their available BNB or PIRI token balances from the system using `withdrawBnbWallet` or `withdrawToken` functions.

This structure can be used to build a DEX protocol on **Pirichain**, or enhance existing exchange integrations by providing automated, blockchain-based trading and liquidity management.

{% code lineNumbers="true" %}

```javascript
// PIRICHAIN SWAP INTEGRATION FOR BNB CHAIN BNB COIN
const parity='BNB_PIRI';
const slippage=0.15;
 async function swapInitialize()
{
    PSDATA[parity]={};
    PSDATA[parity].asks=[];
    PSDATA[parity].bids=[];
    PSDATA['lastPrice']=0;
    PSDATA['volumeDaily']=[];
    PSDATA['slippageFeeCrypto']=0;
    PSDATA['slippageFeeToken']=0;
    const result= await Map.saveMap(JSON.stringify(PSDATA));
    return result;
}

async function checkMyBNBDeposit()
{
        const myBalanceObj=await getBnbWalletBalance();
        const myBalance=parseFloat(myBalanceObj.data);
        const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
        if (hasTx.data)
            return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};
        if (myBalance>0)
        {
            let withdrawalResultForPSCE={};
            checkWalletInitialization();
            if (ORIGINFLAG)
            {
                const scenarioWeb3WalletAddress=await createPSceBnbWallet();
                withdrawalResultForPSCE=await withdrawBnbWallet(scenarioWeb3WalletAddress.data); 
            }
            PSDATA[EXECUTER_ADDRESS].liquidityCrypto+=myBalance;
            const depositLiqResult=await Map.saveMap(JSON.stringify(PSDATA));
            return {depositLiqResult:depositLiqResult,withdrawalResultForPSCE:withdrawalResultForPSCE};
        }
        else
            return {error:1,message:'There is no BNB at your address'};
}

async function depositToken()
{
    if (isNaN(ASSETID))
        return {error:-1,message:'AssetID Must be declared,cannot be NAN!'};
    if (ASSETID!==-1)
        return {error:-1,message:'AssetID Must be -1 for PIRI Coin!'};
    if (isNaN(AMOUNT))
        return {error:-1,message:'Amount Must be declared,cannot be NAN!'};
    if (AMOUNT<=0)
        return {error:-1,message:'Amount Must be declared, cannot be zero or negative!'};
    checkWalletInitialization();
            PSDATA[EXECUTER_ADDRESS].liquidityToken+=AMOUNT;
            const depositTokenResult=await Map.saveMap(JSON.stringify(PSDATA));
            return depositTokenResult;
}

async function getMyDepositWallet()
{
    return await createBnbWallet();
}

async function checkWalletInitialization()
{
    if (PSDATA[EXECUTER_ADDRESS]==undefined)
        {
            PSDATA[EXECUTER_ADDRESS]={};
            PSDATA[EXECUTER_ADDRESS].bids=[];
            PSDATA[EXECUTER_ADDRESS].asks=[];
            PSDATA[EXECUTER_ADDRESS].volume=0;
            PSDATA[EXECUTER_ADDRESS].liquidityCrypto=0;
            PSDATA[EXECUTER_ADDRESS].liquidityToken=0;
        }
}
async function blockWallet(walletAddress,reason)
{
    if (OWNER_ADDRESS!==EXECUTER_ADDRESS)
    return {error:1,message:'This function must be run by authorized!'};

    if (PSDATA['blockedAddress']==undefined)
        PSDATA['blockedAddress']=[];
        PSDATA['blockedAddress'].push({wallet:walletAddress,reason:reason});
        const blockedAddresses=await Map.saveMap(JSON.stringify(PSDATA));
        return blockedAddresses;
}

async function unBlockWallet(walletAddress)
{
    if (OWNER_ADDRESS!==EXECUTER_ADDRESS)
    return {error:1,message:'This function must be run by authorized!'};

    if (PSDATA['blockedAddress']==undefined)
        return {error:1,message:'There is no blocked addresses'};
        PSDATA['blockedAddress']=PSDATA['blockedAddress'].filter(e=>e.wallet===walletAddress);
        const blockedAddresses=await Map.saveMap(JSON.stringify(PSDATA));
        return blockedAddresses;
}


async function buyToken(timeStamp)
{
        if (PSDATA['blockedAddress']!=undefined)
        {
            if (PSDATA['blockedAddress'].find(r=>r.wallet===EXECUTER_ADDRESS))
                return {error:1,message:'Your wallet has been blocked!'};
        }

        const currentAsk=PSDATA[parity].asks.find(r=>r.dateTime===timeStamp);
        if (!currentAsk)
        return {error:1,message:'There is no asks table record by your given timeStamp!'};
        else
        {
            if (PSDATA[EXECUTER_ADDRESS].liquidityCrypto<currentAsk.quantity*currentAsk.level)
            return {error:1,message:'Insufficient Crypto Balance!'};

            PSDATA[parity].asks=PSDATA[parity].asks.filter(f=>f.dateTime!==timeStamp);
            PSDATA[currentAsk.wallet].asks=PSDATA[currentAsk.wallet].asks.filter(f=>f.dateTime!==timeStamp);

            PSDATA[currentAsk.wallet].liquidityToken-=currentAsk.quantity;
            PSDATA[currentAsk.wallet].liquidityCrypto+=currentAsk.quantity*currentAsk.level*(1-slippage);
            PSDATA['slippageFeeCrypto']+=currentAsk.quantity*currentAsk.level*(slippage);
            
            PSDATA[EXECUTER_ADDRESS].liquidityToken+=currentAsk.quantity*(1-slippage);
            PSDATA['slippageFeeToken']+=currentAsk.quantity*slippage;

            PSDATA[EXECUTER_ADDRESS].liquidityCrypto-=currentAsk.quantity*currentAsk.level;

            const buyTokenResult=await Map.saveMap(JSON.stringify(PSDATA));
            return buyTokenResult;
        }
}

async function sellToken(timeStamp)
{
        if (PSDATA['blockedAddress']!=undefined)
        {
            if (PSDATA['blockedAddress'].find(r=>r.wallet===EXECUTER_ADDRESS))
                return {error:1,message:'Your wallet has been blocked!'};
        }

        const currentBids=PSDATA[parity].bids.find(r=>r.dateTime===timeStamp);
        if (!currentBids)
        return {error:1,message:'There is no asks table record by your given timeStamp!'};
        else
        {
            if (PSDATA[EXECUTER_ADDRESS].liquidityToken<currentBids.quantity)
            return {error:1,message:'Insufficient Quantity Balance!'};

            PSDATA[parity].bids=PSDATA[parity].bids.filter(f=>f.dateTime!==timeStamp);
            PSDATA[currentBids.wallet].bids=PSDATA[currentBids.wallet].bids.filter(f=>f.dateTime!==timeStamp);

            PSDATA[currentBids.wallet].liquidityToken+=currentBids.quantity*(1-slippage);
            PSDATA['slippageFeeToken']+=currentBids.quantity*slippage;

            PSDATA[currentBids.wallet].liquidityCrypto-=currentBids.quantity*currentBids.level;
            PSDATA[EXECUTER_ADDRESS].liquidityToken-=currentBids.quantity;
            
            PSDATA[EXECUTER_ADDRESS].liquidityCrypto+=currentBids.quantity*currentBids.level*(1-slippage);
            PSDATA['slippageFeeCrypto']+=currentBids.quantity*currentBids.level*(slippage);
            

            const buyTokenResult=await Map.saveMap(JSON.stringify(PSDATA));
            return buyTokenResult;
        }
}
async function removeMyBid(timeStamp)
{
    checkWalletInitialization();
    const currentRecord=PSDATA[EXECUTER_ADDRESS].bids.find(r=>r.dateTime===timeStamp);
    if (currentRecord)
    {   
            PSDATA[EXECUTER_ADDRESS].bids=PSDATA[EXECUTER_ADDRESS].bids.filter(f=>f.dateTime!==timeStamp);
            PSDATA[EXECUTER_ADDRESS].liquidityCrypto+=currentRecord.quantity*currentRecord.level;
            PSDATA[parity].bids=PSDATA[parity].bids.filter(f=>f.dateTime!==timeStamp);
            const removingBidResult=await Map.saveMap(JSON.stringify(PSDATA));
            return removingBidResult;
    }
}

async function listMyRecord()
{
    return PSDATA[EXECUTER_ADDRESS];
}
async function listTables()
{
    return {
        bids:PSDATA[parity].bids,
        asks:PSDATA[parity].asks
    }
}
async function removeMyAsk(timeStamp)
{
    checkWalletInitialization();
    const currentRecord=PSDATA[EXECUTER_ADDRESS].asks.find(r=>r.dateTime===timeStamp);
    if (currentRecord)
    {   
            PSDATA[EXECUTER_ADDRESS].asks=PSDATA[EXECUTER_ADDRESS].asks.filter(f=>f.dateTime!==timeStamp);
            PSDATA[parity].asks=PSDATA[parity].asks.filter(f=>f.dateTime!==timeStamp);
            PSDATA[EXECUTER_ADDRESS].liquidityToken+=currentRecord.quantity;
            const removingAskResult=await Map.saveMap(JSON.stringify(PSDATA));
            return removingAskResult;
    }
}

async function addBid(quantity,level)
{
        if (PSDATA[EXECUTER_ADDRESS].liquidityCrypto>=quantity*level)
        {
            checkWalletInitialization();
            PSDATA[EXECUTER_ADDRESS].bids.push({quantity:quantity,level:level,dateTime:new Date().getTime()});
            PSDATA[parity].bids.push({wallet:EXECUTER_ADDRESS, quantity:quantity,level:level,dateTime:new Date().getTime()});
            PSDATA[EXECUTER_ADDRESS].liquidityCrypto-=quantity*level;
            const addingBidResult=await Map.saveMap(JSON.stringify(PSDATA));
            return addingBidResult;
        }
        else
        return {error:1,message:'Insufficent BNB Balance'};
}

async function addAsk(quantity,level)
{
        if (PSDATA[EXECUTER_ADDRESS].liquidityToken>=quantity)
        {
            checkWalletInitialization();
            PSDATA[EXECUTER_ADDRESS].asks.push({quantity:quantity,level:level,dateTime:new Date().getTime()});
            PSDATA[parity].asks.push({wallet:EXECUTER_ADDRESS,quantity:quantity,level:level,dateTime:new Date().getTime()});
            PSDATA[EXECUTER_ADDRESS].liquidityToken-=quantity;
            const addingBidResult=await Map.saveMap(JSON.stringify(PSDATA));
            return addingBidResult;
        }
        else
        return {error:1,message:'Insufficent Token'};
}


async function withdrawBnbWallet(withdrawalAddress)
{
    const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
    if (hasTx.data)
            return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};

    if (!withdrawalAddress)
        return {error:1,message:'Wrong Format! Please Fix It'};
    if (withdrawalAddress==='')
        return {error:1,message:'Wrong Format! Please Fix It'};
    if (withdrawalAddress.length!=42)
        return {error:1,message:'Wrong Format! Please Fix It'};

    if (PSDATA[EXECUTER_ADDRESS].liquidityCrypto<=0)
    return {error:1,message:'Insufficient Balance!'};
    
    if (Validator.isHex(withdrawalAddress.substr(2,withdrawalAddress.length-2)))
    {
        let withdrawResult={}
        if (ORIGIN_FLAG)
        {
           withdrawResult= await withdrawBnbPSceWallet(withdrawalAddress);
        }
        PSDATA[EXECUTER_ADDRESS].liquidityCrypto=0;
        const wResult=await Map.saveMap(JSON.stringify(PSDATA));
        return {addingBidResult:addingBidResult,withdrawResult:wResult};
    }
    else
    return {error:1,message:'Malformed BNB Address Format!'};
}
async function withdrawToken()
{
         const hasTx=await Transaction.checkPoolTransaction(EXECUTER_ADDRESS);
        if (hasTx.data)
            return {error:1,message:'There is a transaction processing... System cannot start a new transaction..'};

        if (PSDATA[EXECUTER_ADDRESS].liquidityToken<=0)
            return {error:1,message:'Insufficient Balance!'};
            const transferResult=await Transaction.sendPIRI(EXECUTER_ADDRESS,parseFloat(PSDATA[EXECUTER_ADDRESS].liquidityToken));    
            PSDATA[EXECUTER_ADDRESS].liquidityToken=0;
            const wResult=await Map.saveMap(JSON.stringify(PSDATA));
            return {wResult:wResult,transferResult:transferResult};
}

```

{% endcode %}
