Skip to content

Commit

Permalink
feat: Add TS viewer wallet integration guide
Browse files Browse the repository at this point in the history
  • Loading branch information
micwallace committed Dec 22, 2023
1 parent 3ea55f8 commit 2de08b8
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 1 deletion.
3 changes: 2 additions & 1 deletion pages/tokenscript/_meta.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"tokenscript-cli": "TokenScript CLI",
"extra-features": "Extra Features"
"extra-features": "Extra Features",
"wallets": "Wallets"
}
3 changes: 3 additions & 0 deletions pages/tokenscript/wallets/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"viewer-integration": "Integrate with TokenScript viewer"
}
123 changes: 123 additions & 0 deletions pages/tokenscript/wallets/viewer-integration.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
description: Add TokenScript support to your own wallet using TokenScript viewer
---

# 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

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 [email protected] for any questions or support.

0 comments on commit 2de08b8

Please sign in to comment.