Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/staging'
Browse files Browse the repository at this point in the history
  • Loading branch information
micwallace committed Oct 26, 2023
2 parents ee89ce1 + 84318ce commit 56e2a59
Show file tree
Hide file tree
Showing 47 changed files with 1,710 additions and 484 deletions.
18 changes: 18 additions & 0 deletions javascript/engine-js/src/TokenScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {AttestationDefinitions} from "./tokenScript/attestation/AttestationDefin
import {Attestation} from "./attestation/Attestation";
import {Origin, OriginType} from "./tokenScript/Origin";
import {ITokenContextData} from "./tokens/ITokenContextData";
import {Meta} from "./tokenScript/Meta";

export interface ITokenContext extends ITokenCollection {
originId: string
Expand Down Expand Up @@ -61,6 +62,8 @@ export class TokenScript {

private label?: Label;

private meta?: Meta;

private origins?: { [originName: string]: Origin };

private contracts?: { [contractName: string]: Contract };
Expand Down Expand Up @@ -250,11 +253,26 @@ export class TokenScript {
return this.label.getValue() ?? this.getName() ?? "Unnamed TokenScript";
}

/**
* The metadata for the TokenScript
*/
public getMetadata(){

if (!this.meta)
this.meta = new Meta(this.tokenDef.documentElement);

return this.meta;
}

/**
* An array of cards for the TokenScript
* @param tokenOrigin Use the specified origin name if provided, otherwise fallback to current context origin
*/
public getCards(tokenOrigin?: string): Card[] {

if (!tokenOrigin)
tokenOrigin = this.getCurrentTokenContext()?.originId;

if (!this.cards) {

let cardsXml = this.tokenDef.documentElement.getElementsByTagName("ts:card");
Expand Down
17 changes: 16 additions & 1 deletion javascript/engine-js/src/tokenScript/Attribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {EthUtils} from "../ethereum/EthUtils";
import {BigNumber} from "bignumber.js";
import {FilterQuery} from "./data/event/FilterQuery";
import {AbstractDependencyBranch} from "./data/AbstractDependencyBranch";
import {Label} from "./Label";

interface TokenAttributeValue {
[tokenId: string]: any
Expand All @@ -20,6 +21,7 @@ export class Attribute {

private static NO_DEPENDENCY_ORIGINS = ["ts:user-entry", "ts:data"];

private label?: Label;
private asType?: string;
private scopeValues: TokenAttributeValue = {};

Expand All @@ -38,6 +40,17 @@ export class Attribute {
return this.attributeDef.getAttribute("name");
}

/**
* The label for the attribute
*/
public getLabel(){

if (!this.label)
this.label = new Label(this.attributeDef);

return this.label.getValue() ?? this.getName();
}

/**
* The origin of the attribute
*/
Expand Down Expand Up @@ -323,7 +336,9 @@ export class Attribute {
public invalidate(dependentOn?: string[]){

if (dependentOn){
if (!this.invalidateDependencies(dependentOn) && dependentOn.indexOf(this.getName()) === -1) {
if (!this.invalidateDependencies(dependentOn)) {
if (dependentOn.indexOf(this.getName()) > -1)
return false;
console.log("Attribute '" + this.getName() + "' is not dependent on '" + JSON.stringify(dependentOn) + "', skipping invalidation");
return false;
}
Expand Down
11 changes: 9 additions & 2 deletions javascript/engine-js/src/tokenScript/Card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ export class Card {
return this.view.getAttribute("urlFragment")
}

get uiButton() {
return this.view.hasAttribute("uiButton") ? (this.view.getAttribute("uiButton") === 'true') : true;
}

/**
* Determines whether the view is to be loaded from a URL or from embedded content in ts:view
*/
Expand Down Expand Up @@ -206,9 +210,12 @@ export class Card {
/**
* Returns true if the action is allowed, or a reason string if disabled.
* The reason string is the label of the ts:selection element in the TokenScript file
* @param tokenContext The token context for which to determine card availability
* @param tokenContext The token context for which to determine card availability, falls back to the current token context
*/
public async isEnabledOrReason(tokenContext: ITokenIdContext) {
public async isEnabledOrReason(tokenContext?: ITokenIdContext) {

if (!tokenContext)
tokenContext = this.tokenScript.getCurrentTokenContext();

if (!this.isAvailableForOrigin(tokenContext.originId))
return false;
Expand Down
52 changes: 52 additions & 0 deletions javascript/engine-js/src/tokenScript/Meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* The meta element is placed in the ts:token element and provides metadata details for the tokenscript file.
* Currently, description & aboutUrl are used.
* It supports multi-language
*/
export class Meta {

private static META_TAGS = ["description", "aboutUrl"];

private readonly meta: {[metaTag: string]: string} = {};

constructor(private parentElem: Element) {

const meta = parentElem.getElementsByTagName("ts:meta");

if (meta.length && meta[0].children.length){

for (const tag of Meta.META_TAGS) {

const elements: Element[] = [].slice.call(meta[0].getElementsByTagName("ts:" + tag));

if (!elements.length)
continue;

// TODO: get meta based on locale
const langLabels = elements.filter((elem) => elem.getAttribute("xml:lang") === "en")

this.meta[tag] = langLabels.length ? langLabels[0].textContent : elements[0].textContent;
}
}
}

/**
* The applicable value of the meta, based on the pluralQty provided
* @param name
*/
public getValue(name: string){

if (!this.meta[name])
return null;

return this.meta[name];
}

get description(){
return this.getValue("description")
}

get aboutUrl(){
return this.getValue("aboutUrl")
}
}
2 changes: 1 addition & 1 deletion javascript/engine-js/src/tokens/ITokenCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
import {ITokenDetail} from "./ITokenDetail";

export type TokenType = "erc20" | "erc721" | "eas";
export type TokenType = "erc20" | "erc721" | "erc1155" | "eas";

export type BlockChain = "eth" | "offchain";

Expand Down
1 change: 1 addition & 0 deletions javascript/engine-js/src/tokens/ITokenDetail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface ITokenDetail {
image?: string;
attributes?: NFTAttribute[];
data?: IAttestationData | any;
balance?: string // For ERC1155
}

export interface NFTAttribute {
Expand Down
1 change: 1 addition & 0 deletions javascript/engine-js/src/view/ViewController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export enum ViewEvent {
GET_USER_INPUT = "getUserInput",
EXECUTE_CALLBACK = "executeCallback",
ON_CONFIRM = "onConfirm",
TRANSACTION_EVENT = "transactionEvent"
}

export enum RequestFromView {
Expand Down
10 changes: 10 additions & 0 deletions javascript/tokenscript-viewer/src/assets/icon/info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions javascript/tokenscript-viewer/src/assets/icon/question.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 51 additions & 6 deletions javascript/tokenscript-viewer/src/assets/test-iframe-provider.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,65 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<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="width: 600px; margin: 0 auto; min-height: 800px; position: relative; height: 100vh;">
<iframe id="frame" src="https://viewer-staging.tokenscript.org/?viewType=joyid-token&chain=11155111&contract=0xA04664f6191D9A65F5F48c6F9d6Dd81CB636E65c&tokenId=1"
<!-- ERC1155: http://localhost:3333/?viewType=joyid-token&chain=11155111&contract=0xdE915aFf3649568E15A94fe9b623Db3e7A0944F9&tokenId=1 -->
<!-- ERC1155 fungible: http://localhost:3333/?viewType=joyid-token&chain=11155111&contract=0xdE915aFf3649568E15A94fe9b623Db3e7A0944F9&tokenId=3 -->
<!-- devcon: http://localhost:3333/?viewType=joyid-token&chain=1&contract=0x3c7e352481f4b2fdec1e642a3f0018661c77513d&tokenId=398233297468566556333642 -->
<div style="max-width: 600px; width: 100%; margin: 0 auto; min-height: 700px; position: relative; height: 100vh;">
<iframe id="frame" src=""
style="border: 0; width: 100%; height: 100%;"></iframe>
</div>
<div style="padding: 10px;">
<button class="frame-btn" data-params="chain=11155111&contract=0xA04664f6191D9A65F5F48c6F9d6Dd81CB636E65c&tokenId=1">Seplia SmartCat</button>
<button class="frame-btn" data-params="chain=1&contract=0x3c7e352481f4b2fdec1e642a3f0018661c77513d&tokenId=398233297468566556333642">Eth Devcon</button>
<button class="frame-btn" data-params="chain=11155111&contract=0xdE915aFf3649568E15A94fe9b623Db3e7A0944F9&tokenId=1">Seplia ERC1155</button>
</div>
<script>
// Load iframe
const BASE_URL = "http://localhost:3333/";

let params;

const currentParams = new URLSearchParams(document.location.search);

if (currentParams.has("chain") && currentParams.has("contract") && currentParams.has("tokenId")){
params = new URLSearchParams();
params.set("chain", currentParams.get("chain"));
params.set("contract", currentParams.get("contract"));
params.set("tokenId", currentParams.get("tokenId"));
} else {
params = new URLSearchParams("chain=11155111&contract=0xA04664f6191D9A65F5F48c6F9d6Dd81CB636E65c&tokenId=1"); // smart cat sepolia
//params = new URLSearchParams("chain=1&contract=0x3c7e352481f4b2fdec1e642a3f0018661c77513d&tokenId=398233297468566556333642"); // devcon
//params = new URLSearchParams("chain=11155111&contract=0xdE915aFf3649568E15A94fe9b623Db3e7A0944F9&tokenId=1"); // ERC1155
}

params.set("viewType", "joyid-token");

loadIframeUrl(BASE_URL + "?" + params.toString())

function loadIframeUrl(url){
document.getElementById("frame").src = url;
}

for (const button of document.getElementsByClassName("frame-btn")){
button.addEventListener("click", (evt) => {
const params = new URLSearchParams(evt.target.getAttribute("data-params"));
params.set("viewType", "joyid-token");
loadIframeUrl(BASE_URL + "?" + params.toString())
});
}
</script>
<script>
// Metamask provider

const provider = new ethers.providers.Web3Provider(window.ethereum);
const iframe = document.getElementById("frame");

window.addEventListener("message", async (message) => {
if (message.origin !== "https://viewer-staging.tokenscript.org")
if (message.origin !== "http://localhost:3333")
return;

if (message.data.jsonrpc !== "2.0")
Expand All @@ -35,12 +80,12 @@
case "eth_blockNumber":
case "eth_estimateGas":
case "eth_sendTransaction":
case "eth_sendRawTransaction":
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;
Expand All @@ -67,7 +112,7 @@
data.error = error;
}

iframe.contentWindow.postMessage(data, "https://viewer-staging.tokenscript.org");
iframe.contentWindow.postMessage(data, "http://localhost:3333");
}
</script>
</body>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Large diffs are not rendered by default.

171 changes: 114 additions & 57 deletions javascript/tokenscript-viewer/src/assets/tokenscripts/smart-cat.tsml

Large diffs are not rendered by default.

Loading

0 comments on commit 56e2a59

Please sign in to comment.