
Security News
Package Maintainers Call for Improvements to GitHub’s New npm Security Plan
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
@apillon/wallet-sdk
Advanced tools
Apillon Embedded Wallet JS SDK.
More info can be found in the Apillon wiki.
React + TypeScript + Vite
Ethers v6 used internally
Build is done with vite library mode. Typescript support provided with vite-plugin-dts.
SDK is centered around the EmbeddedWallet
class. This class exposes methods for working with Oasis Sapphire chain authentication.
Initialize the class once by using EmbeddedWalletSDK()
utility, with optional configuration:
/**
* The Apillon integration UUID, obtained from the Apillon Developer Console
*/
clientId: string;
/**
* Network ID for network (chain) selected on first use
*/
defaultNetworkId?: number;
/**
* Configuration of available networks. Oasis Sapphire is always included (ids 23294 and 23295)
*/
networks?: Network[];
/**
* Substrate networks. If no network is provided, substrate is disabled.
*
* You can use `SubstrateNetworks` const or your own network details.
*/
networksSubstrate?: Network[];
/**
* Method for authenticating with passkey to make it global.
*/
passkeyAuthMode: 'redirect' | 'popup' | 'tab_form' = 'redirect';
/**
* Register wallet as an injected web3 wallet, which can then be used via @polkadot/extension-dapp
* @url https://polkadot.js.org/docs/extension/usage
*/
injectPolkadot?: boolean;
The class instance is then available on window (embeddedWallet
) and can be obtained with the getEmbeddedWallet()
utility.
The SDK exposes some events on its events
property.
events
has Typescript support and Events
type from SDK can be used to add types to handlers:
import { Events } from '@apillon/wallet-sdk';
const onDataUpdated = (params: Events['dataUpdated']) => {
// ...
};
signatureRequest
e.g. display UI with message and approve/decline buttons
txApprove
e.g. display UI with transaction details and approve/decline buttons
txSubmitted
e.g. log the transaction in session storage or own backend
wallet.events.on('txSubmitted', tx => {
console.log(tx);
});
txDone
Emitted by UI after a submitted tx is consisdered done (ethereum provider listener)
dataUpdated
Emitted after state data changes, e.g. for keeping track of active account
requestChainChange
Emitted when tx chainId is different from defaultNetworkId. Must be resolve()'d to continue with the tx execution.
providerRequestAccounts
Triggered in 'eth_requestAccounts' provider request handler. Payload is resolver fn that should be invoked when user's account is available (after sign in / register)
EIP-1193 events: connect
, disconnect
, chainChanged
, accountsChanged
open
Emit to open or close Embedded wallet UI
addToken
Emit to programmatically add an ERC20 token
addTokenNft
Emit to programmatically add an NFT token
addTokenStatus
Emitted when addToken
or addTokenNft
resolves.
register
Create new "wallet" for username.
Creates a new contract for each account on sapphire network.
authenticate
Check that credentials belong to some account.
getAccountBalance
getAccountPrivateKey
getAccountWallets
Get all wallets added on user's account. Requires authentication.
addAccountWallet
Add new wallet or import from privateKey.
getAddress
Get "currently active" account address.
getCurrentWallet
Get "currently active" account wallet.
signMessage
submitTransaction
Prepare transaction and emit txSubmitted
event (to show tx in tx history in UI e.g.).
To be used after sending transaction through anything else than broadcastTransaction
.
Doesn't do anything by itself, just for logging/parsing transactions.
signContractWrite
Get signed tx for making a contract write call.
processGaslessMethod
Call a contract method with a gasless transaction (app owner pays for the transaction fees instead of user).
EVM specific API is available in window.embeddedWallet.evm
getRpcProviderForNetworkId
signPlainTransaction
Authenticate with selected auth strategy through sapphire "Account Manager", then return signed tx data and chainId of tx.
broadcastTransaction
Send raw transaction data to network.
If chainId is provided, the transaction is sent to that network (cross-chain).
contractRead
Get result of contract read.
Utility function, this has nothing to do with Oasis.
Substrate specifc API is available in window.embeddedWallet.ss
getApiForNetworkId
Get polkadot.js API object for network (defaultNetworkId
if none provided)
signTransaction
Sign a polkadot extrinsic. Either directly, e.g. api.tx.balances.transferAllowDeath
, or a prepared SignerPayloadJSON
.
broadcastTransaction
This parameter can be used for wallet actions that require user confirmation. If set to true
, the event signatureRequest
/txApprove
will be emitted with resolve()
method passed in payload. Once resolve is called, the action continues. This can be used to display tx confirmation UI e.g.
Initialize SDK, then get the provider using getProvider()
.
import { getProvider as getEmbeddedProvider } from '@apillon/wallet-sdk';
This can then be used as an injected ethereum provider, e.g. with ethers:
new ethers.providers.Web3Provider(getEmbeddedProvider(), 'any');
or wagmi:
const wagmiConfig = {
...,
connectors: [
new InjectedConnector({
chains,
options: {
getProvider() {
return getEmbeddedProvider() as any;
},
},
}),
],
}
SDK must be initialized first, then the EmbeddedEthersSigner
adapter can be used to work with ethers api.
import { EmbeddedEthersSigner } from '@apillon/wallet-sdk';
import { ethers } from 'ethers';
const signer = new EmbeddedEthersSigner(ethProvider);
// Sign message
const signed = await signer.signMessage('Please sign here');
// Use contract
const testContract = new ethers.Contract(
'0xb1051231231231231231231231231231234D0663',
contractAbi,
signer
);
SDK must be initialized first, then the EmbeddedViemAdapter
can be used to work with viem.
import { EmbeddedViemAdapter } from '@apillon/wallet-sdk';
import { createPublicClient, createWalletClient, getContract, http } from 'viem';
import { moonbaseAlpha } from 'viem/chains';
const adapter = new EmbeddedViemAdapter();
const acc = adapter.getAccount();
// Sign
const signed = await acc.signMessage({ message: 'Please sign here via viem' });
// Use contract
const testContract = getContract({
address: '0xb1058eD01451B947A836dA3609f88C91804D0663',
abi: contractAbi,
client: {
public: createPublicClient({
chain: moonbaseAlpha,
transport: http(),
}),
wallet: createWalletClient({
chain: moonbaseAlpha,
transport: http('https://rpc.testnet.moonbeam.network'),
account: acc,
}),
},
});
Must set injectPolkadot
in configuration to true
.
This will register the standard signer and options for injected wallets and allow you to use the @polkadot/extension-dapp
interface.
https://polkadot.js.org/docs/extension/usage
/**
* Sign a raw message
*/
async function signMessage() {
await web3Enable('my cool dapp');
const allAccounts = await web3Accounts();
const account = allAccounts.find(a => a.meta.source === 'apillon-embedded-wallet');
if (!account) {
// no embedded wallet account
return;
}
const injector = await web3FromSource(account.meta.source);
const signRaw = injector?.signer?.signRaw;
if (!!signRaw) {
console.log(
await signRaw({
address: account.address,
data: stringToHex('message to sign'),
type: 'bytes',
})
);
}
}
/**
* Sign a polkadot.js transaction (extrinsic)
*/
async function signTransaction() {
await web3Enable('my cool dapp');
const w = getEmbeddedWallet();
const api = await w?.ss.getApiForNetworkId();
if (!api) {
// no polkadot api
return;
}
const allAccounts = await web3Accounts();
const account = allAccounts.find(a => a.meta.source === 'apillon-embedded-wallet');
if (!account) {
// no embedded wallet account
return;
}
const injector = await web3FromSource(account.meta.source);
const transferExtrinsic = api.tx.balances.transferAllowDeath(
'5H6Ym2FDEn8u5sfitLyKfGRMMZhmp2u855bxQBxDUn4ekhbK',
0.01 * 1e12
);
transferExtrinsic
.signAndSend(
account.address,
{ signer: injector.signer, withSignedTransaction: true },
({ status }) => {
if (status.isInBlock) {
console.log(`Completed at block hash #${status.asInBlock.toString()}`);
} else {
console.log(`Current status: ${status.type}`);
}
}
)
.catch((error: any) => {
console.log(':( transaction failed', error);
});
}
A default wallet UI can be added by using EmbeddedWalletUI()
. This includes a react app that handles logged in state and transaction confirmations etc.
import { DefaultEthereumNetworks, DefaultSubstrateNetworks } from '@apillon/wallet-sdk';
import { EmbeddedWalletUI } from '@apillon/wallet-ui';
EmbeddedWalletUI('#wallet', {
clientId: 'YOUR INTEGRATION UUID HERE',
defaultNetworkId: 1287,
networks: DefaultEthereumNetworks,
networksSubstrate: DefaultSubstrateNetworks,
});
FAQs
▶◀ Apillon Embedded Wallet SDK ▶◀
We found that @apillon/wallet-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
Product
Socket Firewall is a free tool that blocks malicious packages at install time, giving developers proactive protection against rising supply chain attacks.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.