Integrate Web3Auth with the Polymesh Blockchain
While using the Web3Auth Web SDK for a non-EVM chain like Polymesh
you get a standard provider from which you can get the private key of the user. Using this private
key, you can use the corresponding libraries of the blockchain to make blockchain calls like getting
the user's public signing key
, fetching balance
, and sign & send transaction
. We have
highlighted a few methods here to get you started quickly on that.
Installation
For Polymesh, we will use the libraries @polymeshassociation/polymesh-sdk
and
@polymeshassociation/local-signing-manager
to create the Polymesh address, query the chain and
submit transactions.
- npm
- Yarn
- pnpm
npm install --save @polymeshassociation/polymesh-sdk @polymeshassociation/local-signing-manager
yarn add @polymeshassociation/polymesh-sdk @polymeshassociation/local-signing-manager
pnpm add @polymeshassociation/polymesh-sdk @polymeshassociation/local-signing-manager
Initializing Provider
Getting the chainConfig
- Mainnet
- Testnet
const chainConfig = {
chainNamespace: "other",
chainId: "0x1",
rpcTarget: "https://mainnet-rpc.polymesh.network",
// Avoid using public rpcTarget in production.
displayName: "Polymesh Mainnet",
blockExplorerUrl: "https://polymesh.subscan.io",
ticker: "POLYX",
tickerName: "Polymesh",
};
const chainConfig = {
chainNamespace: "other",
chainId: "0x5", //
rpcTarget: "https://testnet-rpc.polymesh.live",
// Avoid using public rpcTarget in production.
displayName: "Polymesh Testnet",
blockExplorerUrl: "https://polymesh-testnet.subscan.io",
ticker: "POLYX",
tickerName: "Polymesh",
};
Initializing and instantiating the Web3Auth SDK
- PnP Modal SDK
- PnP NoModal SDK
- Single Factor Auth JS 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,
});
import { Web3AuthNoModal } from "@web3auth/no-modal";
import { AuthAdapter } from "@web3auth/auth-adapter";
import { CommonPrivateKeyProvider } from "@web3auth/base-provider";
import { WEB3AUTH_NETWORK, CHAIN_NAMESPACES } from "@web3auth/base";
const privateKeyProvider = new CommonPrivateKeyProvider({
config: { chainConfig },
});
const web3auth = new Web3AuthNoModal({
clientId, // Get it from Web3Auth Dashboard
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
});
const authAdapter = new AuthAdapter();
web3auth.configureAdapter(authAdapter);
import { Web3Auth } from "@web3auth/single-factor-auth";
import { CommonPrivateKeyProvider } from "@web3auth/base-provider";
import { WEB3AUTH_NETWORK, CHAIN_NAMESPACES } from "@web3auth/base";
const web3auth = new Web3Auth({
clientId, // Get your Client ID from Web3Auth Dashboard
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
});
const privateKeyProvider = new CommonPrivateKeyProvider({
config: { chainConfig },
});
Getting the Web3Auth provider
After initializing Web3Auth, the next step is to initialize the provider and use it for your operations.
- PnP Modal SDK
- PnP NoModal SDK
- Single Factor Auth JS SDK
// 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`
// Initialize for PnP NoModal SDK
await web3auth.init();
// Trigger the login
await web3auth.connectTo("auth");
// Get the provider
const provider = web3auth.provider;
// Continue using the `provider`
// Initialize for Single Factor Auth JS SDK
await web3auth.init();
// 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 Account and KeyPair
Once a user logs in, the Web3Auth SDK returns a provider. Since Web3Auth doesn't have a native provider for Polymesh, we need to directly use the private key to make the RPC calls.
Using the function, web3auth.provider.request({method: "private_key"})
from Web3Auth provider, the
application can have access to the user's private key. However, Web3Auth does not provide direct
access to Polymesh-specific signing functions, hence, we create a new LocalSigningManager
and
import this private key to give the Polymesh SDK the ability to sign transactions with this key.
import { LocalSigningManager } from "@polymeshassociation/local-signing-manager";
/*
Use code from the above Initializing Provider here
*/
// web3authProvider is web3auth.provider from above
const privateKey = await web3authProvider.request({ method: "private_key" });
// create and instance of the polymesh local signing manager and import the web3Auth private hey
const localSigningManager = await LocalSigningManager.create({
accounts: [{ uri: "0x" + privateKey, derivationPath: "" }],
// A derivation path can optionally be added to derive multiple keys from the same private key
});
At this point if we were to query the public key derived from the private key by calling
localSigningManager.getAccounts()
the function would throw an error as a SS58 prefix for the chain
has not been set. The SS58 prefix can be set manually by calling e.g.
localSigningManager.setSs58Format(12)
, or by attaching the signing manager to an instance of the
Polymesh SDK which will automatically read the correct SS58 prefix from the chain and set it in the
signing manager.
- Mainnet
- Testnet
import { Polymesh } from "@polymeshassociation/polymesh-sdk";
// Create an instance of the Polymesh SDK, attaching the previously
// created signing manager and connect to a Polymesh RPC node
const polymeshApi = await Polymesh.connect({
nodeUrl: "wss://mainnet-rpc.polymesh.network/",
signingManager: localSigningManager,
});
// Query the derived Public key from the Polymesh SDK instance
const signingAccount = polymeshApi.accountManagement.getSigningAccount();
// Note: if you have added multiple signing keys to the signing manager
// the default signing account will be the first key added
console.log(`Public Key: ${signingAccount.address}`);
import { Polymesh } from "@polymeshassociation/polymesh-sdk";
// Create an instance of the Polymesh SDK, attaching the previously
// created signing manager and connect to a Polymesh RPC node
const polymeshApi = await Polymesh.connect({
nodeUrl: "wss://testnet-rpc.polymesh.live/",
signingManager: localSigningManager,
});
// Query the derived Public key from the Polymesh SDK instance.
const signingAccount = polymeshApi.accountManagement.getSigningAccount();
// Note: if you have added multiple signing keys to the signing manager
// the default signing account will be the first key added
console.log(`Public Key: ${signingAccount.address}`);
Get Balance
/*
Use code from the above Initializing Provider and connecting to Polymesh here
*/
// Retrieve the POLYX balance associate with the signing key
const balance = await polymeshApi.accountManagement.getAccountBalance();
Get The Associated Identity ID
Before a key on Polymesh can receive tokens or transact on chain it must be associated with an onchain identity. A new identity can be assigned by a permissioned Certified Due Diligence (CDD) provider or you can add the key to an existing identity. Individuals can onboard their key by visiting https://testnet-onboarding.polymesh.live/ or https://mainnet-onboarding.polymesh.network/.
/*
Use code from the above Initializing Provider and connecting to Polymesh here
*/
// Retrieve the Identity associate with the signing key
const identity = await polymeshApi.getSigningIdentity();
console.log(`Signing Identity: ${identity?.did || "No identity found"}`);
Send Transaction
/*
Use code from the above Initializing Provider and connecting to Polymesh here
*/
import { BigNumber } from "@polymeshassociation/polymesh-sdk";
import type { GenericPolymeshTransaction } from '@polymeshassociation/polymesh-sdk/types';
// Prepare a POLYX transfer transaction from the signer added previously
const polyxTransferTx = await polymeshApi.network.transferPolyx(
{
amount: new BigNumber(10);,
to: "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
memo: "I sent some POLYX", //optional
}
);
console.log(`\nTransferring ${amount.toString()} POLYX from ${signingAccount.address} to ${to}`);
// Optionally subscribe to transaction status changes and handle status changes
const unsub = polyxTransferTx.onStatusChange(
(tx: GenericPolymeshTransaction<any, any>) => {
// Do something on status changes
},
);
try {
// Execute the PolyX transfer transaction
await polyxTransferTx.run();
} catch (error) {
console.log("Transaction Error:", (error as Error).message);
} finally {
// Unsubscribe from transaction status changes
unsub();
}
console.log(JSON.stringify(polyxTransferTx.receipt?.events));