Unofficial Node.js library for multiple Mojang HTTP APIs.
npm i mojang
This library is for use with Node.js, and comes with TypeScript type definitions. All functions are async or promises.
const mojang = require('mojang')
Look up profile IDs from current (or previous) in-game names. If a username or profile ID does not exist, these functions resolve with falsy values. These functions may throw errors if names are too long or profile IDs are not UUIDs.
await mojang.username('direwolf20')
// { name: 'direwolf20', id: 'bbb87dbe690f4205bdc572ffb8ebc29d' }
await mojang.usernames(['direwolf20'])
// [ { id, name }, ... ]
await mojang.profile('bbb87dbe690f4205bdc572ffb8ebc29d')
// { id, name }
await mojang.history('bbb87dbe690f4205bdc572ffb8ebc29d')
// [{ name }, { name, changedToAt }, ...]
The API status endpoint isn't always accurate, but is available.
await mojang.status()
// { 'api.mojang.com': 'green', ... }
Mojang's sales statistics are available too.
await mojang.statistics()
// { total, last24h, saleVelocityPerSeconds }
Authenticated sessions may be created to play Minecraft or change skins. For reference, the official launcher generates a client token with UUID v4, and saves it forever.
let session = await mojang.authenticate(email, secret, clientToken)
// { accessToken, clientToken, user, availableProfiles, selectedProfile }
// Or throws if credentials are wrong
The accessToken
should be saved as part of a "stay logged in" feature. Before launching the game, check that a saved token is still valid.
await mojang.validate(session)
// true or false
If validate
returns false, a launcher should attempt to refresh the session. This could create a new access token and invalidate the old token. It might also throw an error.
session = await mojang.refresh(session)
// { accessToken, clientToken, user, selectedProfile }
When a user wants to log out, invalidate their current access token.
await mojang.invalidate(session)
The access token appears to be a JWT and can be decoded. sub
is the user ID, spr
is the selected profile ID, yggt
is the original access token from earlier Yggdrasil versions, and iss
is always "Yggdrasil-Auth".
const { JWT } = require("jose");
JWT.decode(accessToken)
// { sub, yggt, spr, iss, exp, iat }
Before changing skins, a user's IP must be trusted. Changing skins on minecraft.net will prompt the user the trust their current IP address by asking security questions.
Alternatively, this library's challenges
and answers
functions can be used to implement your own interface for answering the user's security questions. See https://wiki.vg/Mojang_API#Security_question-answer_flow for more information.
await isTrusted(accessToken)
// false
await challenges(accessToken)
// [{}, ...]
await answers(accessToken, answerList)
To change skins, use a stream or buffer with uploadSkin
, or use a image URL with setSkin
. The function resetSkin
will return the profile to a Steve or Alex skin, depending on the profile's ID.
const skinStream = fs.createReadStream(skinFile)
await mojang.uploadSkin(accessToken, profileId, skinStream, isSlimBool)
// or
await mojang.setSkin(accessToken, profileId, skinUrl, isSlimBool)
// or
await mojang.resetSkin(accessToken, profileId)
A profile's default skin is either Alex or Steve, derived from the profile's ID. This function uses Crafatar's logic.
mojang.isAlex(profileId)
// true or false
Get a profile's session for skin and cape data. This function reshapes the response JSON to be a bit more developer friendly, but the original, decoded textures
dictionary is also available. This endpoint is severely rate-limited. See https://wiki.vg/Mojang_API#UUID_-.3E_Profile_.2B_Skin.2FCape for more information.
await mojang.session('bbb87dbe690f4205bdc572ffb8ebc29d')
/*
{
name: 'direwolf20',
slim: false,
skin: 'http://textures.minecraft.net/texture/4c7b0468044bfecacc43d00a3a69335a834b73937688292c20d3988cae58248d',
cape: undefined,
textures: {},
signature: ""
}
*/
Promises and async try/catch are supported. If the server responds with an error code and JSON, the thrown error might have the property error.response.body
which contains the server's JSON. 401 status codes are thrown on some endpoints that did not get valid access tokens.
try {
await mojang.authenticate(email, secret, clientToken);
// ...
} catch (error) {
// https://github.com/sindresorhus/got#errors
// error.name === "HTTPError"
// error.response.statusCode === 403
// https://wiki.vg/Authentication#Errors
// error.response.body.error === "ForbiddenOperationException"
// error.response.body.errorMessage === "Invalid credentials. Invalid username or password."
}
This library may be used to create Minecraft launchers with Electron. This library uses got internally, so using it in the main process or with electron.remote
is necessary.
Modern browsers and Electron renderer processes will prohibit requests to Mojang's APIs because they do not support CORS, at the time of writing.
I'm still learning how to maintain projects or contribute to open source in general. All PRs, issues, and general feedback are welcome!
ESLint and TypeScript are used to lint the source.
Because Mojang's APIs might spontaneously change, it makes sense to test integration with the live endpoints, instead of mock responses. The file test/online.js can be run using AVA with the necessary environment variables set. I recommend direnv for setting environment variables. Wait between sequential tests and remember to reset the test account's skin afterwards.
Project originally by @jamen.
This repository is not affiliated with Mojang.
"Minecraft" is a trademark of Mojang Synergies AB.
Generated using TypeDoc