-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add TS viewer wallet integration guide
- Loading branch information
1 parent
3ea55f8
commit 2de08b8
Showing
3 changed files
with
128 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"viewer-integration": "Integrate with TokenScript viewer" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |