Integrate using TokenScript viewer
The easiest way to integrate TokenScript into your wallet is using the TokenScript viewer integration solution. Integrating in this way allows you to stay up to date with new TokenScript features without deploying new versions of your wallet.
Prerequisites
This method currently requires that your wallet is a JavaScript/TypeScript application. This includes web app frameworks like Ionic or Electron. We are still working on a native integration that will allow native Android & iOS to embed TokenScript viewer in a similar way. If you are interested in the native integration please reach out to us to voice your support.
The NFT details view
TokenScript viewer provides a custom view that displays an NFT details screen and the actions for the corresponding TokenScript. Here is an example: https://viewer.tokenscript.org/?viewType=sts-token&chain=137&contract=0xD5cA946AC1c1F24Eb26dae9e1A53ba6a02bd97Fe&tokenId=3803829543 (opens in a new tab)
If you require a different UI, please reach out to us. We would be happy to create a design which better reflects your wallets current UI.
Step 1: Open the viewer in an iframe
Within your application, extend or replace your NFT details screen with an iframe that loads the following URL:
https://viewer.tokenscript.org/?viewType=sts-token&chain=${CHAIN}&contract=${CONTRACT}&tokenId=${TOKEN_ID}
(Note: you must replace the CHAIN, CONTRACT & TOKEN_ID with the dynamic values corresponding to the token selected in the wallet)
Step 2: Implement the postMessage listener for RPC
The iframe will proxy any RPC requests through postMessage to the parent window where your wallet app runs. To implement message & transaction signing, you must listen and process these requests. This is different for each wallet, so we can only provide guidance and a simple example to help you along.
Here is a self-contained example using MetaMask RPC provider & ethers.js:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ethers/5.7.2/ethers.umd.min.js" integrity="sha512-FDcVY+g7vc5CXANbrTSg1K5qLyriCsGDYCE02Li1tXEYdNQPvLPHNE+rT2Mjei8N7fZbe0WLhw27j2SrGRpdMg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body style="margin: 0;">
<div style="max-width: 600px; width: 100%; margin: 0 auto; position: relative; height: 100dvh;">
<iframe id="frame" src="https://viewer.tokenscript.org/?viewType=sts-token&chain=137&contract=0xD5cA946AC1c1F24Eb26dae9e1A53ba6a02bd97Fe&tokenId=3803829543"style="border: 0; width: 100%; height: 100%;"></iframe>
</div>
<script>
const BASE_URL = "https://viewer.tokenscript.org";
// Metamask provider
const provider = new ethers.providers.Web3Provider(window.ethereum);
const iframe = document.getElementById("frame");
window.addEventListener("message", async (message) => {
if (message.origin !== BASE_URL)
return;
if (message.data.jsonrpc !== "2.0")
return;
console.log("[IFRAME_RPC] request received: ", message);
try {
switch (message.data.method) {
case "eth_accounts":
case "eth_requestAccounts":
await window.ethereum.enable();
const accounts = await provider.listAccounts();
sendResponse(message.data, accounts);
break;
case "eth_chainId":
case "net_version":
case "eth_blockNumber":
case "eth_estimateGas":
case "eth_sendTransaction":
case "eth_getTransactionByHash":
case "eth_getTransactionReceipt":
case "eth_getTransactionCount":
case "personal_sign":
case "eth_signTypedData":
case "wallet_switchEthereumChain":
const result = await provider.send(message.data.method, message.data.params);
sendResponse(message.data, result);
break;
default:
sendResponse(message.data, null, {code: -1, message: "RPC Method " + message.data.method + " is not implemented"});
}
} catch (e){
console.error(e);
sendResponse(message.data, null, {
code: e.code,
message: e.message
});
}
});
function sendResponse(messageData, response, error){
const data = messageData;
if (response){
data.result = response;
} else {
data.error = error;
}
iframe.contentWindow.postMessage(data, BASE_URL);
}
</script>
</body>
</html>
As you can see, the code required is minimal. It simply forwards the request to your own RPC provider and returns the result back to the iframe.
Troubleshooting
To test transactions you'll need a SmartToken and testnet support. STL can provide you with test tokens on Sepolia & Mumbai networks. We will soon have a faucet on the Smart Token Store that will allow you to self-mint a SmartToken.
You can email sayhi@smarttokenlabs.com for any questions or support.