It is strongly discouraged to use private key or mnemonic import/generate function, if you use it, you need to secure the data yourself, Particle's SDK has no relationship with the imported/generated mnemonic or private key.
Run this command:
npm install @particle-network/rn-connect
click here to get the demo source code
Make sure that your project meets the following requirements:
- Targets API Level 23 (Marshmallow) or higher
- Uses Android 6.0 or higher
- Uses Jetpack (AndroidX)
- Java 11
Configure project information,Refer to here
android {
...
defaultConfig {
......
manifestPlaceholders["PN_PROJECT_ID"] = "your project id"
manifestPlaceholders["PN_PROJECT_CLIENT_KEY"] = "your project client key"
manifestPlaceholders["PN_APP_ID"] = "your app id"
}
//How you quote wallet sdk, you must set it
dataBinding {
enabled = true
}
}
- Install the following:
- Xcode 14.1 or later.
- Make sure that your project meets the following requirements:
- Your project must target these platform versions or later:
- iOS 14
- Your project must target these platform versions or later:
3.1 After export iOS project, open your_project_name.xcworkspace
under ios folder, here its name is ParticleConnectExample.xcworkspace.
3.2 Create a ParticleNetwork-Info.plist into the root of your Xcode project, and make sure the file is checked under Target Membership.
3.3 Copy the following text into this file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PROJECT_UUID</key>
<string>YOUR_PROJECT_UUID</string>
<key>PROJECT_CLIENT_KEY</key>
<string>YOUR_PROJECT_CLIENT_KEY</string>
<key>PROJECT_APP_UUID</key>
<string>YOUR_PROJECT_APP_UUID</string>
</dict>
</plist>
3.4 Replace YOUR_PROJECT_UUID
, YOUR_PROJECT_CLIENT_KEY
, and YOUR_PROJECT_APP_UUID
with the new values created in your Dashboard
3.5. Import the particle-auth
module in your AppDelegate.m
file.
{% tabs %} {% tab title="Objective-C" %}
#import <react_native_particle_connect/react_native_particle_connect-Swift.h>
{% endtab %} {% endtabs %}
3.6. Add the scheme URL handle in your app's application(_:open:options:)
method
{% tabs %} {% tab title="Objective-C" %}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([ParticleConnectSchemeManager handleUrl:url] == YES) {
return YES;
} else {
// other methods
}
return YES;
}
{% endtab %} {% endtabs %}
3.7. Configure your app scheme URL, select your app from TARGETS
, under Info
section, click + to add the URL types
, and paste your scheme in URL Schemes
Your scheme URL should be "pn" + your project app uuid.
For example, if your project app id is "63bfa427-cf5f-4742-9ff1-e8f5a1b9828f", your scheme URL is "pn63bfa427-cf5f-4742-9ff1-e8f5a1b9828f".
3.8 In Xcode right-click your Info.plist
file and choose "Open As Source Code".
Copy & Paste the XML snippet into the body of your file (<dict>
...</dict>
).
<key>LSApplicationQueriesSchemes</key>
<array>
<string>imtokenv2</string>
<string>metamask</string>
<string>phantom</string>
<string>bitkeep</string>
<string>trust</string>
<string>rainbow</string>
<string>zerion</string>
<string>mathwallet</string>
<string>1inch</string>
<string>awallet</string>
<string>okex</string>
</array>
3.9 Edit Podfile, you should follow Podfile required to edit Podfile.
import * as particleConnect from '@particle-network/rn-connect';
Before using the sdk you have to call init(Required)
// Get your project id and client key from dashboard,
// https://dashboard.particle.network/
ParticleInfo.projectId = ''; // your project id
ParticleInfo.clientKey = ''; // your client key
{% hint style="info" %}
Starting from version 0.14.0, WalletConnectV2 is supported.
// Init particle connect SDK,
// metadata is your app info, will pass to wallet when wallet connect.
// you can use the values that we provided in example.
const chainInfo = ChainInfo.EthereumGoerli;
const env = Env.Dev;
const metadata = new DappMetaData('75ac08814504606fc06126541ace9df6',
'Particle Connect',
'https://connect.particle.network/icons/512.png',
'https://connect.particle.network',
'Particle Wallet', "", "");
particleConnect.init(chainInfo, env, metadata);
// set wallet connect support chaininfos, if you dont call this method
// default value is current chaininfo.
const chainInfos = [Ethereum, Polygon, EthereumGoerli, EthereumSepolia];
particleConnect.setWalletConnectV2SupportChainInfos(chainInfos);
{% endhint %}
you can use our SDK as a web3 provider
import Web3 from 'web3';
// Start with new web3, at this time, you don't connect with this walletType, and dont know any publicAddress
var newWeb3: Web3;
// After connected a wallet, restoreWeb3 when getAccounts.
// We need to check if the walletType and publicAddress is connected.
var web3: Web3;
newWeb3_getAccounts = async () => {
try {
const accounts = await newWeb3.eth.getAccounts();
pnaccount = new PNAccount("","",accounts[0] as string,"");
console.log('web3.eth.getAccounts', accounts);
} catch (error) {
console.log('web3.eth.getAccounts', error);
}
}
restoreWeb3_getAccounts = async () => {
try {
console.log('pnaccount.publicAddress ', pnaccount.publicAddress);
web3 = restoreWeb3('your project id', 'your client key', PNAccount.walletType, pnaccount.publicAddress);
const accounts = await web3.eth.getAccounts();
console.log('web3.eth.getAccounts', accounts);
} catch (error) {
console.log('web3.eth.getAccounts', error);
}
}
web3_getBalance = async () => {
try {
const accounts = await web3.eth.getAccounts();
const balance = await web3.eth.getBalance(accounts[0]);
console.log('web3.eth.getBalance', balance);
} catch (error) {
console.log('web3.eth.getBalance', error);
}
}
web3_getChainId = async () => {
try {
const chainId = await web3.eth.getChainId();
console.log('web3.eth.getChainId', chainId);
} catch (error) {
console.log('web3.eth.getChainId', error);
}
}
web3_personalSign = async () => {
// for persion_sign
// don't use web3.eth.personal.sign
try {
const accounts = await web3.eth.getAccounts();
const result = await web3.currentProvider.request({
method: 'personal_sign',
params: ['hello world', accounts[0]]
});
console.log('web3.eth.personal.sign', result);
} catch (error) {
console.log('web3.eth.personal.sign', error);
}
}
web3_signTypedData_v4 = async () => {
try {
const accounts = await web3.eth.getAccounts();
const result = await web3.currentProvider.request({
method: 'eth_signTypedData_v4',
params: [accounts[0], { 'your typed data v4' }]
});
console.log('web3 eth_signTypedData_v4', result);
} catch (error) {
console.log('web3 eth_signTypedData_v4', error);
}
}
web3_sendTransaction = async () => {
try {
const accounts = await web3.eth.getAccounts();
const result = await web3.eth.sendTransaction(
{
from: accounts[0],
to: 'a receiver address or contract address',
value: '1000000',
data: '0x'
}
)
console.log('web3.eth.sendTransaction', result);
} catch (error) {
console.log('web3.eth.sendTransaction', error);
}
}
web3_wallet_switchEthereumChain = async () => {
try {
const chainId = "0x" + EvmService.currentChainInfo.chain_id.toString(16);
const result = await web3.currentProvider.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId }]
})
console.log('web3 wallet_switchEthereumChain', result);
} catch (error) {
console.log('web3 wallet_switchEthereumChain', error);
}
}
web3_wallet_addEthereumChain = async () => {
try {
const chainId = "0x" + EvmService.currentChainInfo.chain_id.toString(16);
const result = await web3.currentProvider.request({
method: 'wallet_addEthereumChain',
params: [{ chainId }]
})
console.log('web3 wallet_addEthereumChain', result);
} catch (error) {
console.log('web3 wallet_addEthereumChain', error);
}
}
// connect example
const result = await particleConnect.connect(PNAccount.walletType);
if (result.status) {
console.log('connect success');
const account = result.data;
this.pnaccount = new PNAccount(
account.icons,
account.name,
account.publicAddress,
account.url
);
console.log('pnaccount = ', this.pnaccount);
} else {
console.log('connect failure');
const error = result.data;
console.log(error);
}
};
// connect with particle, support pass more parameters
// set login type, account, support types and login form mode
const connectConfig = new ParticleConnectConfig(LoginType.Phone, '', [
SupportAuthType.Email,
SupportAuthType.Google,
SupportAuthType.Apple,
]);
const result = await particleConnect.connect(
WalletType.Particle,
connectConfig
);
if (result.status) {
console.log('connect success');
const account = result.data;
this.pnaccount = new PNAccount(
account.icons,
account.name,
account.publicAddress,
account.url
);
console.log('pnaccount = ', this.pnaccount);
} else {
console.log('connect failure');
const error = result.data;
console.log(error);
}
};
const publicAddress = TestAccountEVM.publicAddress;
const result = await particleConnect.disconnect(walletType, publicAddress);
if (result.status) {
console.log(result.data);
} else {
const error = result.data;
console.log(error);
}
const publicAddress = pnaccount.publicAddress;
const isConnected = await particleConnect.isConnected(walletType, publicAddress);
console.log(isConnected);
const publicAddress = pnaccount.publicAddress;
const domain = "login.xyz";
const uri = "https://login.xyz/demo#login";
const result = await particleConnect.login(walletType, publicAddress, domain, uri);
if (result.status) {
const message = result.data.message;
loginSourceMessage = message;
const signature = result.data.signature;
loginSignature = signature
console.log("login message:", message);
console.log("login signature:", signature);
} else {
const error = result.data;
console.log(error);
}
const publicAddress = pnaccount.publicAddress;
const message = loginSourceMessage;
const signature = loginSignature;
console.log("verify message:", message);
console.log("verify signature:", signature);
const result = await particleConnect.verify(walletType, publicAddress, message, signature);
if (result.status) {
const flag = result.data;
console.log(flag);
} else {
const error = result.data;
console.log(error);
}
const message = "Hello world!"
const publicAddress = pnaccount.publicAddress;
const result = await particleConnect.signMessage(walletType, publicAddress, message);
if (result.status) {
const signedMessage = result.data;
console.log(signedMessage);
} else {
const error = result.data;
console.log(error);
}
const transaction = ""
const publicAddress = pnaccount.publicAddress;
const result = await particleConnect.signTransaction(walletType, publicAddress, transaction);
if (result.status) {
const signedTransaction = result.data;
console.log(signedTransaction);
} else {
const error = result.data;
console.log(error);
}
const transactions = ["", ""]
const publicAddress = pnaccount.publicAddress;
const result = await particleConnect.signAllTransactions(walletType, publicAddress, transactions);
if (result.status) {
const signedTransactions = result.data;
console.log(signedTransactions);
} else {
const error = result.data;
console.log(error);
}
const transaction = await Helper.getEthereumTransacion(pnaccount.publicAddress);
console.log(transaction);
const publicAddress = pnaccount.publicAddress;
const result = await particleConnect.signAndSendTransaction(walletType, publicAddress, transaction);
if (result.status) {
const signature = result.data;
console.log("signAndSendTransaction:", signature);
} else {
const error = result.data;
console.log(error);
}
const typedData = "{ \"types\": { \"EIP712Domain\": [ { \"name\": \"name\", \"type\": \"string\" }, { \"name\": \"version\", \"type\": \"string\" }, { \"name\": \"chainId\", \"type\": \"uint256\" }, { \"name\": \"verifyingContract\", \"type\": \"address\" } ], \"Person\": [ { \"name\": \"name\", \"type\": \"string\" }, { \"name\": \"wallet\", \"type\": \"address\" } ], \"Mail\": [ { \"name\": \"from\", \"type\": \"Person\" }, { \"name\": \"to\", \"type\": \"Person\" }, { \"name\": \"contents\", \"type\": \"string\" } ] }, \"primaryType\": \"Mail\", \"domain\": { \"name\": \"Ether Mail\", \"version\": \"1\", \"chainId\": 5, \"verifyingContract\": \"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC\" }, \"message\": { \"from\": { \"name\": \"Cow\", \"wallet\": \"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826\" }, \"to\": { \"name\": \"Bob\", \"wallet\": \"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB\" }, \"contents\": \"Hello, Bob!\" }} ";
const publicAddress = pnaccount.publicAddress;
const result = await particleConnect.signTypedData(walletType, publicAddress, typedData);
if (result.status) {
const signature = result.data;
console.log(signature);
} else {
const error = result.data;
console.log(error);
}
const privateKey = TestAccountEVM.privateKey;
const result = await particleConnect.importPrivateKey(WalletType.EvmPrivateKey, privateKey);
if (result.status) {
const ajavccount = result.data;
console.log(account);
} else {
const error = result.data;
console.log(error);
}
const mnemonic = TestAccountEVM.mnemonic;
const result = await particleConnect.importMnemonic(WalletType.EvmPrivateKey, mnemonic);
if (result.status) {
const account = result.data;
console.log(account);
} else {
const error = result.data;
console.log(error);
}
const publicAddress = TestAccountEVM.publicAddress;
const result = await particleConnect.exportPrivateKey(WalletType.EvmPrivateKey, publicAddress);
if (result.status) {
const privateKey = result.data;
console.log(privateKey);
} else {
const error = result.data;
console.log(error);
}
const accounts = await particleConnect.getAccounts(walletType);
console.log(accounts);
const chainInfo = Ethereum;
const result = await particleConnect.setChainInfoAsync(chainInfo);
console.log(result);
const chainInfo = Ethereum;
const result = await particleConnect.setChainInfo(chainInfo);
console.log(result);
const chainInfo = await ParticleConnect.getChainInfo();
console.log(chainInfo);
for how to connect a wallet, please look at this page , the principle is the same.
addEthereumChain = async () => {
const publicAddress = TestAccountEVM.publicAddress;
const chainId = 80001; // polygon testnet
const result = await particleConnect.addEthereumChain(WalletType.MetaMask, publicAddress, chainId);
if (result.status) {
const data = result.data;
console.log(data);
} else {
const error = result.data;
console.log(error);
}
}
switchEthereumChain = async () => {
const publicAddress = TestAccountEVM.publicAddress;
const chainId = 137; // polygon mainnet
const result = await particleConnect.switchEthereumChain(WalletType.MetaMask, publicAddress, chainId);
if (result.status) {
const data = result.data;
console.log(data);
} else {
const error = result.data;
console.log(error);
}
}
only support iOS, usually use when open app, if current wallet is from wallet connect, call this method to reconnect, you can call this method anywhere anytime.
It is better to start a connection before sign.
reconnectIfNeeded = async () => {
const publicAddress = TestAccountEVM.publicAddress;
const result = await particleConnect.reconnectIfNeeded(
WalletType.MetaMask,
publicAddress
);
if (result.status) {
const data = result.data;
console.log(data);
} else {
const error = result.data;
console.log(error);
}
};