Skip to main content

MiniPay Code Library

Snippets of code that can be used to implement flows inside MiniPay

Get the connected user's address without any Library

// The code must run in a browser environment and not in node environment
if (window && window.ethereum) {
// User has a injected wallet

if (window.ethereum.isMinipay) {
// User is using Minipay

// Requesting account addresses
let accounts = await window.ethereum.request({
method: "eth_requestAccounts",
params: [],
});

// Injected wallets inject all available addresses,
// to comply with API Minipay injects one address but in the form of array
console.log(accounts[0]);
}

// User is not using MiniPay
}

// User does not have a injected wallet

To use the code snippets below, install the following packages:

yarn add @celo/abis @celo/identity viem@1

Check cUSD Balance of an address

const { getContract, formatEther, createPublicClient, http } = require("viem");
const { celo } = require("viem/chains");
const { stableTokenABI } = require("@celo/abis");

const STABLE_TOKEN_ADDRESS = "0x765DE816845861e75A25fCA122bb6898B8B1282a";

async function checkCUSDBalance(publicClient, address) {
let StableTokenContract = getContract({
abi: stableTokenABI,
address: STABLE_TOKEN_ADDRESS,
publicClient,
});

let balanceInBigNumber = await StableTokenContract.read.balanceOf([
address,
]);

let balanceInWei = balanceInBigNumber.toString();

let balanceInEthers = formatEther(balanceInWei);

return balanceInEthers;
}

const publicClient = createPublicClient({
chain: celo,
transport: http(),
}); // Mainnet

let balance = await checkCUSDBalance(publicClient, address); // In Ether unit

Check If a transaction succeeded

const { createPublicClient, http } = require("viem");
const { celo } = require("viem/chains");

async function checkIfTransactionSucceeded(publicClient, transactionHash) {
let receipt = await publicClient.getTransactionReceipt({
hash: transactionHash,
});

return receipt.status === "success";
}

const publicClient = createPublicClient({
chain: celo,
transport: http(),
}); // Mainnet

let transactionStatus = await checkIfTransactionSucceeded(
publicClient,
transactionHash
);

Estimate Gas for a transaction (in Celo)

const { createPublicClient, http } = require("viem");
const { celo } = require("viem/chains");

async function estimateGas(publicClient, transaction, feeCurrency = "") {
return await publicClient.estimateGas({
...transaction,
feeCurrency: feeCurrency ? feeCurrency : "",
});
}

const publicClient = createPublicClient({
chain: celo,
transport: http(),
});

let gasLimit = await estimateGas(publicClient, {
account: "0x8eb02597d85abc268bc4769e06a0d4cc603ab05f",
to: "0x4f93fa058b03953c851efaa2e4fc5c34afdfab84",
value: "0x1",
data: "0x",
});

Estimate Gas for a transaction (in cUSD)

const { createPublicClient, http } = require("viem");
const { celo } = require("viem/chains");

async function estimateGas(publicClient, transaction, feeCurrency = "") {
return await publicClient.estimateGas({
...transaction,
feeCurrency: feeCurrency ? feeCurrency : "",
});
}

const publicClient = createPublicClient({
chain: celo,
transport: http(),
});

const STABLE_TOKEN_ADDRESS = "0x765DE816845861e75A25fCA122bb6898B8B1282a";

let gasLimit = await estimateGas(
publicClient,
{
account: "0x8eb02597d85abc268bc4769e06a0d4cc603ab05f",
to: "0x4f93fa058b03953c851efaa2e4fc5c34afdfab84",
value: "0x1",
data: "0x",
},
STABLE_TOKEN_ADDRESS
);

Estimate Gas Price for a transaction (in Celo)

const { createPublicClient, http } = require("viem");
const { celo } = require("viem/chains");

async function estimateGasPrice(publicClient, feeCurrency = "") {
return await publicClient.request({
method: "eth_gasPrice",
params: feeCurrency ? [feeCurrency] : [],
});
}

const publicClient = createPublicClient({
chain: celo,
transport: http(),
});

let gasPrice = await estimateGasPrice(publicClient);

Estimate Gas Price for a transaction (in cUSD)

const { createPublicClient, http } = require("viem");
const { celo } = require("viem/chains");

async function estimateGasPrice(publicClient, feeCurrency = "") {
return await publicClient.request({
method: "eth_gasPrice",
params: feeCurrency ? [feeCurrency] : [],
});
}

const publicClient = createPublicClient({
chain: celo,
transport: http(),
});

const STABLE_TOKEN_ADDRESS = "0x765DE816845861e75A25fCA122bb6898B8B1282a";

let gasPrice = await estimateGasPrice(publicClient, STABLE_TOKEN_ADDRESS);

Calculate cUSD to be spent for transaction fees

const { createPublicClient, http, formatEther } = require("viem");
const { celo } = require("viem/chains");

const publicClient = createPublicClient({
chain: celo,
transport: http(),
});

const STABLE_TOKEN_ADDRESS = "0x765DE816845861e75A25fCA122bb6898B8B1282a";

// `estimateGas` implemented above
let gasLimit = await estimateGas(
publicClient,
{
account: "0x8eb02597d85abc268bc4769e06a0d4cc603ab05f",
to: "0x4f93fa058b03953c851efaa2e4fc5c34afdfab84",
value: "0x1",
data: "0x",
},
STABLE_TOKEN_ADDRESS
);

// `estimateGasPrice` implemented above
let gasPrice = await estimateGasPrice(publicClient, STABLE_TOKEN_ADDRESS);

let transactionFeesInCUSD = formatEther(gasLimit * hexToBigInt(gasPrice));

Resolve Minipay phone numbers to Addresses

const { createPublicClient, http } = require("viem");
const { celo } = require("viem/chains");
const { privateKeyToAccount } = require("viem/accounts");
const { SocialConnectIssuer } = require("./SocialConnect.js");

let account = privateKeyToAccount(process.env.ISSUER_PRIVATE_KEY);

let walletClient = createWalletClient({
account,
transport: http(),
chain,
});

const issuer = new SocialConnectIssuer(walletClient, {
authenticationMethod: AuthenticationMethod.ENCRYPTION_KEY,
rawKey: process.env.DEK_PRIVATE_KEY,
});

await issuer.initialize();

const identifierType = IdentifierPrefix.PHONE_NUMBER;

/**
* Any phone number you want to lookup
*
* The below phone number is registered on the testnet issuer mentioned below.
*/
const identifier = "+911234567890";

/**
* You can lookup under multiple issuers in one request.
*
* Below is the MiniPay issuer address on Mainnet.
*
* Note: Remember to make your environment variable ENVIRONMENT=MAINNET
*/
let issuerAddresses = ["0x7888612486844Bb9BE598668081c59A9f7367FBc"];

// A testnet issuer we setup for you to lookup on testnet.
// let issuerAddresses = ["0xDF7d8B197EB130cF68809730b0D41999A830c4d7"];

let results = await issuer.lookup(identifier, identifierType, issuerAddresses);

Request an ERC20 token transfer

import { createWalletClient, custom } from 'viem'
// import { celo } from 'viem/chains'
import { celoAlfajores } from 'viem/chains'

const client = createWalletClient({
chain: celoAlfajores,
// chain: celo,
transport: custom(window.ethereum!)
})

const publicClient = createPublicClient({
chain: celoAlfajores,
// chain: celo,
transport: http()
})

async function requestTransfer(tokenAddress, transferValue, tokenDecimals) {

let hash = await client.sendTransaction({
to: tokenAddress,
// to: '0x765DE816845861e75A25fCA122bb6898B8B1282a' // cUSD (Mainnet)
// to: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C' // USDC (Mainnet)
// to: '0x48065fbbe25f71c9282ddf5e1cd6d6a887483d5e' // USDT (Mainnet)
data: encodeFunctionData({
abi: stableTokenAbi, // Token ABI can be fetched from Explorer.
functionName: "transfer",
args: [
receiverAddress,
// Different tokens can have different decimals, cUSD (18), USDC (6)
parseUnits(`${Number(transferValue)}`, tokenDecimals),
],
}),
// If the wallet is connected to a different network then you get an error.
chain: celoAlfajores,
// chain: celo,
});

const transaction = await publicClient.waitForTransactionReceipt({
hash, // Transaction hash that can be used to search transaction on the explorer.
});

if (transaction.status === "success") {
// Do something after transaction is successful.
} else {
// Do something after transaction has failed.
}
}