|
| 1 | +# Integrate Bifrost SLPx on Manta |
| 2 | + |
| 3 | +## Getting started |
| 4 | + |
| 5 | +Make sure you add RPC for Manta. Information can be obtained from [chainlist.org](https://chainlist.org/?search=manta) |
| 6 | + |
| 7 | +Or manual input with the information below |
| 8 | +| Name | Value | |
| 9 | +|---|---| |
| 10 | +| Network Name | Manta Pacific L2 | |
| 11 | +| Description | The public mainnet for Manta Pacific. | |
| 12 | +| Network URL | https://pacific-info.manta.network/ | |
| 13 | +| Explorer URL | https://pacific-explorer.manta.network/ | |
| 14 | +| RPC URL | https://manta-pacific.drpc.org | |
| 15 | +| Chain ID | 169 | |
| 16 | +| Currency Symbol | ETH | |
| 17 | + |
| 18 | +### `MANTA` token |
| 19 | + |
| 20 | +| Name | Value | |
| 21 | +|---|---| |
| 22 | +| Address | [0x95CeF13441Be50d20cA4558CC0a27B601aC544E5](https://pacific-explorer.manta.network/address/0x95CeF13441Be50d20cA4558CC0a27B601aC544E5?tab=internal_txns) | |
| 23 | +| Name | Manta | |
| 24 | +| Symbol | `MANTA` | |
| 25 | +| Decimals | 18 | |
| 26 | + |
| 27 | +### `vMANTA` token |
| 28 | + |
| 29 | +| Name | Value | |
| 30 | +|---|---| |
| 31 | +| Address | [0x7746ef546d562b443AE4B4145541a3b1a3D75717](https://pacific-explorer.manta.network/address/0x7746ef546d562b443AE4B4145541a3b1a3D75717) | |
| 32 | +| Name | vManta | |
| 33 | +| Symbol | `vManta` | |
| 34 | +| Decimals | 18 | |
| 35 | +| ABI | [VoucherMantaOFT.json](https://github.com/bifrost-io/slpx-contracts/blob/main/deployments/manta/VoucherMantaOFT.json) | |
| 36 | + |
| 37 | + |
| 38 | +### `MantaPacificSlpx` contract |
| 39 | + |
| 40 | +| Name | Value | |
| 41 | +|---|---| |
| 42 | +| Address | [0x95A4D4b345c551A9182289F9dD7A018b7Fd0f940](https://pacific-explorer.manta.network/address/0x95A4D4b345c551A9182289F9dD7A018b7Fd0f940?tab=internal_txns) | |
| 43 | +| Source code | [MantaPacificSlpx.sol](https://github.com/bifrost-io/slpx-contracts/blob/main/contracts/MantaPacificSlpx.sol) | |
| 44 | +| ABI | [MantaPacificSlpx.json](https://github.com/bifrost-io/slpx-contracts/blob/main/deployments/manta/MantaPacificSlpx.json) | |
| 45 | + |
| 46 | + |
| 47 | +## Integration |
| 48 | + |
| 49 | +Manta Pacific's SLPx currently does not support atomic contract calls. That means you can't integrate within your contract logic. The reason are as follows: |
| 50 | +- the minting process relies on `msg.sender` to be the receiver so this can have unintended effect on your contract logic |
| 51 | +- there is a wait time of about 8 to 10 minutes to receive the `vMANTA` token. |
| 52 | + |
| 53 | +However, you can still interact with the contract directly from the frontend or use another contract but the call is structured at the end of the logic. |
| 54 | + |
| 55 | +There are 3 main functions you use to integrate with `MantaPacificSlpx`: |
| 56 | + |
| 57 | +`minAmount` (derived from the public variable `minAmount`) |
| 58 | +```solidity |
| 59 | +function minAmount() returns (uint256) |
| 60 | +``` |
| 61 | + |
| 62 | +`estimateSendAndCallFee` |
| 63 | +```solidity |
| 64 | +function estimateSendAndCallFee( |
| 65 | + address assetAddress, |
| 66 | + uint256 amount, |
| 67 | + uint32 channel_id, |
| 68 | + uint64 dstGasForCall, |
| 69 | + bytes calldata adapterParams |
| 70 | +) public view returns (uint256) |
| 71 | +``` |
| 72 | + |
| 73 | +`create_order` |
| 74 | +```solidity |
| 75 | +function create_order( |
| 76 | + address assetAddress, |
| 77 | + uint256 amount, |
| 78 | + uint32 channel_id, |
| 79 | + uint64 dstGasForCall, |
| 80 | + bytes calldata adapterParams |
| 81 | +) external payable |
| 82 | +``` |
| 83 | + |
| 84 | +You want to fetch the `minAmount()` function to check on the minimum amount of `MANTA` that you need to use to mint. Currently this value is `2000000000000000000` equal to `2 MANTA`. |
| 85 | + |
| 86 | +Next, you want to call the function `estimateSendAndCallFee` to get the mint fee in ETH. The input values are defined as follows: |
| 87 | + |
| 88 | +| Variable | Input value | Definition | |
| 89 | +|---|---|---| |
| 90 | +| `address assetAddress` | `0x95CeF13441Be50d20cA4558CC0a27B601aC544E5` | Address of `MANTA` token | |
| 91 | +| `uint256 amount` | `uint256` | Amount of `MANTA` token be used to mint to `vMANTA` | |
| 92 | +| `uint32 channel_id` | `0` | ID of the channel | |
| 93 | +| `uint64 dstGasForCall` | `4000000` | Destination gas for call | |
| 94 | +| `bytes calldata adapterParams` | `["uint16", "uint256"], [1, 4200000]` | Parameters to be encoded for the Adapter. Refer to the **adapterParams encoding** section below on how to call | |
| 95 | + |
| 96 | +**adapterParams encoding** |
| 97 | + |
| 98 | +With `Ethers.js v5`, you can use `solidityPack` function |
| 99 | + |
| 100 | +```ts |
| 101 | +ethers.utils.solidityPack(["uint16", "uint256"], [1, 4200000]) |
| 102 | +``` |
| 103 | + |
| 104 | +With `Ethers.js v6` |
| 105 | + |
| 106 | +```ts |
| 107 | +solidityPacked(["uint16", "uint256"], [1, 4200000]) |
| 108 | +``` |
| 109 | + |
| 110 | +With `Viem`, you can use `encodePacked` function |
| 111 | + |
| 112 | +```ts |
| 113 | +encodePacked(["uint16", "uint256"], [1, 4200000]) |
| 114 | +``` |
| 115 | + |
| 116 | +### Example Viem integration |
| 117 | + |
| 118 | +`minAmount` |
| 119 | + |
| 120 | +```ts |
| 121 | +const minAmount = await publicClient.readContract({ |
| 122 | + address: "0x95CeF13441Be50d20cA4558CC0a27B601aC544E5", |
| 123 | + abi: mantaSLPxAbi, |
| 124 | + functionName: "minAmount", |
| 125 | +}); |
| 126 | +console.log("minAmount", minAmount); |
| 127 | + |
| 128 | +// Output: minAmount 2000000000000000000n |
| 129 | +``` |
| 130 | + |
| 131 | +`estimateSendAndCallFee` |
| 132 | + |
| 133 | +```ts |
| 134 | +const sendAndCallFee = await publicClient.readContract({ |
| 135 | + address: "0x95A4D4b345c551A9182289F9dD7A018b7Fd0f940", |
| 136 | + abi: mantaSLPxAbi, |
| 137 | + functionName: "estimateSendAndCallFee", |
| 138 | + args: [ |
| 139 | + "0x95CeF13441Be50d20cA4558CC0a27B601aC544E5", // MANTA token |
| 140 | + parseUnits(3, 18), // amount |
| 141 | + 0, // channel_id |
| 142 | + 4000000, // dstGasForCall |
| 143 | + encodePacked(["uint16", "uint256"], [1, BigInt(4200000)]), // adapterParams |
| 144 | + ], |
| 145 | +}); |
| 146 | +console.log("sendAndCallFee", sendAndCallFee); |
| 147 | + |
| 148 | +// Output: sendAndCallFee 83556372916216n |
| 149 | +``` |
| 150 | +Last call returns a value of `83556372916216` equal to `0.000083556372916216 ETH`. |
| 151 | + |
| 152 | +Then, to mint `vMANTA` with `MANTA`, call `approve` on `MANTA` token contract to the `MantaPacificSlpx` contract, then call the `create_order` function with the same inputs as `estimateSendAndCallFee`. |
| 153 | + |
| 154 | +```ts |
| 155 | +const { request: approvalRequest } = await publicClient.simulateContract({ |
| 156 | + account: currentAddress, // connected address |
| 157 | + address: "0x95CeF13441Be50d20cA4558CC0a27B601aC544E5", |
| 158 | + abi: erc20Abi, |
| 159 | + functionName: "approve", |
| 160 | + args: [ |
| 161 | + "0x95A4D4b345c551A9182289F9dD7A018b7Fd0f940", |
| 162 | + parseUnits(3, 18), |
| 163 | + ], |
| 164 | +}); |
| 165 | +let approvalHash = await walletClient.writeContract(approvalRequest); |
| 166 | +console.log("approvalHash", approvalHash); |
| 167 | + |
| 168 | +const { request: mintRequest } = await publicClient.simulateContract({ |
| 169 | + account: currentAddress, // connected address |
| 170 | + address: "0x95A4D4b345c551A9182289F9dD7A018b7Fd0f940", |
| 171 | + abi: mantaSLPxAbi, |
| 172 | + functionName: "create_order", |
| 173 | + args: [ |
| 174 | + "0x95CeF13441Be50d20cA4558CC0a27B601aC544E5", // MANTA token address |
| 175 | + parseUnits(3, 18), // amount |
| 176 | + 0, // channel_id |
| 177 | + 4000000, // dstGasForCall |
| 178 | + encodePacked(["uint16", "uint256"], [1, BigInt(4200000)]), // adapterParams |
| 179 | + ], |
| 180 | + value: sendAndCallFee as bigint, |
| 181 | +}); |
| 182 | + |
| 183 | +hash = await walletClient.writeContract(request); |
| 184 | +transaction = await publicClient.waitForTransactionReceipt({ |
| 185 | + hash: hash, |
| 186 | +}); |
| 187 | +console.log("hash", hash); |
| 188 | +``` |
| 189 | + |
| 190 | +Then wait for 8 to 10 minutes to receive the `vMANTA` token in the caller address. |
| 191 | + |
| 192 | +### Example Wagmi integration |
| 193 | + |
| 194 | +`minAmount` |
| 195 | + |
| 196 | +```ts |
| 197 | +const { data: minAmount } = useReadContract({ |
| 198 | + ...wagmiContractConfig, |
| 199 | + address: "0x95CeF13441Be50d20cA4558CC0a27B601aC544E5", |
| 200 | + abi: mantaSLPxAbi, |
| 201 | + functionName: "minAmount", |
| 202 | +}); |
| 203 | +console.log("minAmount", minAmount); |
| 204 | + |
| 205 | +// Output: minAmount 2000000000000000000n |
| 206 | +``` |
| 207 | + |
| 208 | +`estimateSendAndCallFee` |
| 209 | + |
| 210 | +```ts |
| 211 | +const { data: sendAndCallFee } = useReadContract({ |
| 212 | + ...wagmiContractConfig, |
| 213 | + address: "0x95A4D4b345c551A9182289F9dD7A018b7Fd0f940", |
| 214 | + abi: mantaSLPxAbi, |
| 215 | + functionName: "estimateSendAndCallFee", |
| 216 | + args: [ |
| 217 | + "0x95CeF13441Be50d20cA4558CC0a27B601aC544E5", // MANTA token |
| 218 | + parseUnits(3, 18), // amount |
| 219 | + 0, // channel_id |
| 220 | + 4000000, // dstGasForCall |
| 221 | + encodePacked(["uint16", "uint256"], [1, BigInt(4200000)]), // adapterParams |
| 222 | + ], |
| 223 | +}); |
| 224 | +console.log("sendAndCallFee", sendAndCallFee); |
| 225 | + |
| 226 | +// Output: sendAndCallFee 83556372916216n |
| 227 | +``` |
| 228 | +Last call returns a value of `83556372916216` equal to `0.000083556372916216 ETH`. |
| 229 | + |
| 230 | +Then, to mint `vMANTA` with `MANTA`, call `approve` on `MANTA` token contract to the `MantaPacificSlpx` contract, then call the `create_order` function with the same inputs as `estimateSendAndCallFee`. |
| 231 | + |
| 232 | +```ts |
| 233 | +const { |
| 234 | + data: hash, |
| 235 | + error, |
| 236 | + isPending, |
| 237 | + writeContract |
| 238 | +} = useWriteContract() |
| 239 | + |
| 240 | +async function approveLstContract() { |
| 241 | + writeContract({ |
| 242 | + account: currentAddress, // connected address |
| 243 | + address: "0x95CeF13441Be50d20cA4558CC0a27B601aC544E5", |
| 244 | + abi: erc20Abi, |
| 245 | + functionName: "approve", |
| 246 | + args: [ |
| 247 | + "0x95A4D4b345c551A9182289F9dD7A018b7Fd0f940", |
| 248 | + parseUnits(3, 18), |
| 249 | + ], |
| 250 | + }) |
| 251 | +} |
| 252 | + |
| 253 | +async function mintLst() { |
| 254 | + writeContract({ |
| 255 | + account: currentAddress, // connected address |
| 256 | + address: "0x95A4D4b345c551A9182289F9dD7A018b7Fd0f940", |
| 257 | + abi: mantaSLPxAbi, |
| 258 | + functionName: "create_order", |
| 259 | + args: [ |
| 260 | + "0x95CeF13441Be50d20cA4558CC0a27B601aC544E5", // MANTA token address |
| 261 | + parseUnits(3, 18), // amount |
| 262 | + 0, // channel_id |
| 263 | + 4000000, // dstGasForCall |
| 264 | + encodePacked(["uint16", "uint256"], [1, BigInt(4200000)]), // adapterParams |
| 265 | + ], |
| 266 | + value: sendAndCallFee as bigint, |
| 267 | + }) |
| 268 | +} |
| 269 | + |
| 270 | +const { isLoading: isConfirming, isSuccess: isConfirmed } = |
| 271 | + useWaitForTransactionReceipt({ |
| 272 | + hash, |
| 273 | +}) |
| 274 | +``` |
| 275 | + |
| 276 | +Then wait for 8 to 10 minutes to receive the `vMANTA` token in the caller address. |
0 commit comments