Skip to main content

Integrate Web3Auth with the Near Protocol

While using the Web3Auth Web SDK for a non-EVM chain like NEAR, you get a standard provider from which you can get the user's private key. Using this private key, you can use the corresponding libraries of the blockchain to make blockchain calls like getting a user's account, fetching balance, performing send transaction, etc. To help you get started, we've outlined some methods for you to use.

Installation

npm install --save near-api-js@4.0.4

Initializing Provider

Getting the chainConfig

const chainConfig = {
chainNamespace: "other",
chainId: "0x4e454152",
rpcTarget: "https://mainnet.aurora.dev",
// Avoid using public rpcTarget in production.
displayName: "Near",
blockExplorerUrl: "https://aurorascan.dev",
ticker: "NEAR",
tickerName: "NEAR",
};

Initializing and instantiating the Web3Auth SDK

import { Web3Auth } from "@web3auth/modal";
import { CommonPrivateKeyProvider } from "@web3auth/base-provider";
import { WEB3AUTH_NETWORK, CHAIN_NAMESPACES } from "@web3auth/base";

const privateKeyProvider = new CommonPrivateKeyProvider({
config: { chainConfig: chainConfig },
});

const web3auth = new Web3Auth({
// Get it from Web3Auth Dashboard
clientId,
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
privateKeyProvider: privateKeyProvider,
});

Getting the Web3Auth provider

After initializing Web3Auth, the next step is to initialize the provider and use it for your operations.

// Initialize for PnP Modal SDK
await web3auth.initModal();

// Trigger the login
await web3auth.connect();

// Get the provider
const provider = web3auth.provider;

// Continue using the `provider`

After logging in, the Web3Auth instance will provide you with information regarding the user that is logged in. This information is obtained directly from the JWT token and is not stored by Web3Auth. Therefore, this information can only be accessed through social logins after the user has logged into your application.

const user = await web3auth.getUserInfo(); // web3auth instance

Get Key Pair and Account

After a user logs in, they receive a provider from the Web3Auth SDK. However, there is no native provider for Near in Web3Auth, so we must use the private key to make RPC calls directly.

To access the user's private key, the application can use the function web3auth.provider.request({method: "private_key"}) from the Web3Auth provider. Yet, this key cannot be used with Near since it requires the ed25519 key. Therefore, we must use the getED25519Key() function from @web3auth/base-provider to convert the secp256k1 key to an ed25519 key.

import { connect, KeyPair, keyStores, utils } from "near-api-js";
import { getED25519Key } from "@web3auth/auth-adapter";
/*
Use code from the above Initializing Provider here
*/

// web3authProvider is web3auth.provider from above
const privateKey = await web3authProvider.request({ method: "private_key" });

// Convert the secp256k1 key to ed25519 key
// When starting your application with "solana" namespace, you can skip the below two lines
// and pass the privateKey directly to buffer.
const privateKeyEd25519 = getED25519Key(privateKey).sk.toString("hex");

// Convert the private key to Buffer
const privateKeyEd25519Buffer = Buffer.from(privateKeyEd25519, "hex");

// Convert the private key to base58
const bs58encode = utils.serialize.base_encode(privateKeyEd25519Buffer);

// Convert the base58 private key to KeyPair
const keyPair = KeyPair.fromString(`ed25519:${bs58encode}`);

// publicAddress
const publicAddress = keyPair?.getPublicKey().data || [];

// accountId is the account address on Near which is where funds will be sent to.
const accountId = Buffer.from(pk58 || []).toString("hex");

Get Balance

import { connect, keyStores, utils } from "near-api-js";
/*
Use code from the above Initializing Provider here
*/
const myKeyStore = new keyStores.InMemoryKeyStore();
await myKeyStore.setKey("testnet", accountId, keyPair); // accountId and keyPair from above
const connectionConfig = {
networkId: "testnet",
keyStore: myKeyStore,
nodeUrl: "https://rpc.testnet.near.org",
walletUrl: "https://wallet.testnet.near.org",
helperUrl: "https://helper.testnet.near.org",
explorerUrl: "https://explorer.testnet.near.org",
};
const nearConnection = await connect(connectionConfig);
const account = await nearConnection.account(accountId);
const accountBalance = await account.getAccountBalance();
const availableBalance = utils.format.formatNearAmount(accountBalance.available);

Send Transaction

import { connect, keyStores, utils } from "near-api-js";
/*
Use code from the above Initializing Provider here
*/
const receiver = "shahbaz17.testnet";
const amount = "2"; // in NEAR
const myKeyStore = new keyStores.InMemoryKeyStore();
await myKeyStore.setKey("testnet", accountId, keyPair); // accountId and keyPair from above
const connectionConfig = {
networkId: "testnet",
keyStore: myKeyStore,
nodeUrl: "https://rpc.testnet.near.org",
walletUrl: "https://wallet.testnet.near.org",
helperUrl: "https://helper.testnet.near.org",
explorerUrl: "https://explorer.testnet.near.org",
};
const nearConnection = await connect(connectionConfig);
const senderAccount = await nearConnection.account(accountId);
const result = await senderAccount.sendMoney(receiver, utils.format.parseNearAmount(amount));