Skip to content

Instantly share code, notes, and snippets.

@mikeymop
Last active June 7, 2022 04:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikeymop/644d3245c89252ed612465974e2b5e81 to your computer and use it in GitHub Desktop.
Save mikeymop/644d3245c89252ed612465974e2b5e81 to your computer and use it in GitHub Desktop.
This gets the uri of an nft pfp from the social.picture.value of an Unstoppable Domain
var https = require('https');
var resolveNFTUri = function (self, str, store, cache, actions, channel) {
log = function (msg) { console.log("getNFT: \n", msg); };
log('Finding nft uri for: ', str);
str = str[0];
var getChainId = function (str) {
var chainEnum = {
1: 'eth',
25: 'cro',
56: 'bnb',
137: 'polygon',
250: 'fantom',
43114: 'avax',
1666600000: 'one',
};
var re = /\d+(?=\/)/;
var res = str.match(re);
return chainEnum[res[0]];
}
/** When given a social.picture.value returns the token type as a string */
var getTokenValue = function (str) {
const re = /(erc721|erc1155)/
return str.match(re)[0];
}
/** When given a social.picture.value returns the eth-like address as a string */
var getAddress = function (str) {
var re = /0x[a-zA-Z0-9]{40}/;
return str.match(re)[0];
}
var getFullTokenId = function (str) {
var [, tokenId] = str.split(':');
console.log('got tokenId of: ', tokenId);
return tokenId;
}
/** Some NFTs may have image data stored directly on the token.
* In this case we dont need to transofmr an ipfs url, and can send
* the data to discord directly.
* See: https://stackoverflow.com/a/65676660
*/
var directWriteMessage = function (str) {
log("Image stored directly in asset, sending message automatically.")
var payload = str.split(",")[1];
log("Payload: ");
console.log(payload);
const nftBuffer = new Buffer.from(payload, "base64");
const { MessageAttachment } = require('discord.js')
const attachment = new MessageAttachment(nftBuffer, "output.png");
channel.send(attachment)
}
var chainId = getChainId(str);
var tokenId = getTokenValue(str);
var addr = getAddress(str);
var fullAddr = getFullTokenId(str);
var path = '/api/v2/nft/' + fullAddr + '?chain=' + chainId + '&format=decimal';
console.log('Calling: https://deep-index.moralis.io' + path);
var request = https.request({
host: 'deep-index.moralis.io',
path: path,
// port: 443,
method: 'GET',
headers: {
'X-API-Key': apiKey,
'Accept' : 'application/json'
}
}, function (response) {
var data = '';
response.on('data', function (chunk) {
data = data + chunk.toString();
});
response.on('end', function () {
try {
var json = JSON.parse(data);
var metadata = JSON.parse(json.metadata);
log(metadata.image);
if (metadata.image === null || metadata.image === undefined) {
throw new Error(
"No image metadata present, are there issues with the UD api?"
+ metadata
)
}
if (metadata.image.split("/")[0] === 'data:image') {
directWriteMessage(metadata.image);
store(true, 2, "pfpSent", cache);
actions.callNextAction(cache);
}
store(metadata.image, 2, "pfpURL", cache) // tried this more recently
actions.callNextAction(cache);
} catch (e) {
log(e);
store(true, 2, "pfpErr", cache);
}
});
});
request.end();
};
var self = this;
self.msg = () => console.log('Msg sent');
this.storeValue = () => console.log('Storing value');
var Actions = {};
var cache = {};
/** Returns void or the ipfs location of nft image.
* Modifies the following DBM vars:
* - pfpErr {true | false} - Whether there was an error or not
* - pfpURL {string | void} - The uri of the nft, ipfs:// or https://
* - pfpSent {true | false} - The image was stored directly in the nft.
* This function sent had the bot send the message already no further action needed.
*/
const channel = client.channels.cache.get(tempVars('channel'));
resolveNFTUri(self, [badStringJ], this.storeValue, cache, Actions, channel);
// let channel = bot.channels.cache.find((channel) => channel.id === "983505894488805449");
// channel.send("Channel worked");
var fetch = require('node-fetch');
var apiKey = '';
var tokenId = '';
/** Returns void or the ipfs location of nft image.
* Modifies the following DBM vars:
* - pfpErr {true | false} - Whether there was an error or not
* - pfpURL {string | void} - The uri of the nft, ipfs:// or https://
* - pfpSent {true | false} - The image was stored directly in the nft.
* This function sent had the bot send the message already no further action needed.
*/
const resolveNFTUri = async (str, store, cache) => {
log = (msg) => console.log("getNFT: \n", msg);
console.log('Str is: ', str);
str = str[0];
log('Finding nft uri for: ', str);
const getChainId = (str) => {
const chainEnum = {
1: 'eth',
25: 'cro',
56: 'bnb',
137: 'polygon',
250: 'fantom',
43114: 'avax',
1666600000: 'one',
};
const re = /\d+(?=\/)/;
const res = str.match(re);
return chainEnum[res[0]];
}
/** When given a social.picture.value returns the token type as a string */
const getTokenValue = (str) => {
const re = /(erc721|erc1155)/
return str.match(re)[0];
}
/** When given a social.picture.value returns the eth-like address as a string */
const getAddress = (str) => {
var re = /0x[a-zA-Z0-9]{40}/;
return str.match(re)[0];
}
const getFullTokenId = (str) => {
var [, tokenId] = str.split(':');
console.log('got tokenId of: ', tokenId);
return tokenId;
}
/** Some NFTs may have image data stored directly on the token.
* In this case we dont need to transofmr an ipfs url, and can send
* the data to discord directly.
* See: https://stackoverflow.com/a/65676660
*/
const directWriteMessage = async (str) => {
try {
const { DiscordJS, Actions, Images } = this.getDBM();
console.log("Image stored directly in asset, sending message automatically.")
console.log("Getting image body for: ", str);
if (str.split('+')[0].split('/')[1] === 'svg') {
console.log("Got an svg, fancy!");
const nftBuffer = new Buffer.from(str.split(',')[1], 'base64')
// Embedding an svg doesn't work, it needs a uri.
// let embed = new DiscordJS.MessageEmbed().setImage("attachment://nft.svg");
channel.send({
content: "You image sire",
// embed,
files: [new DiscordJS.MessageAttachment(nftBuffer, "nft.svg")],
});
}
} catch (e) {
throw e;
}
};
var chainId = getChainId(str);
var tokenId = getTokenValue(str);
var addr = getAddress(str);
var fullAddr = getFullTokenId(str);
var path = '/api/v2/nft/' + fullAddr + '?chain=' + chainId + '&format=decimal';
console.log('Calling: https://deep-index.moralis.io' + path);
try {
const result = await fetch('https://deep-index.moralis.io' + path, {
method: 'GET',
headers: {
'X-API-Key': apiKey,
'Accept': 'application/json'
}
});
const json = await result.json();
const metadata = JSON.parse(json.metadata);
console.log("Metadata: ", metadata.image);
if (metadata.image === null || metadata.image === undefined) {
throw new Error(
"No image metadata present, are there issues with the UD api?"
+ metadata
)
}
if (metadata.image.split("/")[0] === 'data:image') {
console.log("Svg embedded directly in nft, evaluating...");
// store(true, 2, "pfpSent", cache);
await directWriteMessage(metadata.image);
}
console.log("Function terminating...");
// store(metadata.image, 2, "pfpURL", cache) // tried this more recently
Actions.callNextAction(cache);
} catch (e) {
console.log("rNI error: ", e);
// store(true, 2, "pfpErr", cache);
}
};
(async () => {
channel.send("Looking for your nft...");
const attach = await resolveNFTUri([tokenId], this.storeValue, cache, channel);
// console.log(attach);
console.log('We did something...');
channel.send('Finished');
Actions.callNextAction(cache);
})();
@mikeymop
Copy link
Author

Note getChainId(), getTokenValue() and getAddress() are independent functions. You can cut them out of this code and use them standalone if this is more useful than resolveNFTUri() doing everything in one shot.

@mikeymop
Copy link
Author

mikeymop commented May 30, 2022

You can customize chainEnum to add or remove chains. The chainIds can get identified from chainlist.org.

Just put the chainId on the left, and the value you want that number to become on the right.
eg Adding chainId 7, which resolves to 'testChain', to the enumeration would be like so:

const chainEnum = {
  ...
  7: 'testChain',
  ...
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment