ZekeSnider / NintendoSwitchRESTAPI

Reverse engineered REST API used in the Nintendo Switch app for iOS. Includes documentation on Splatoon 2's API.
MIT License
636 stars 43 forks source link

Animal Crossing API ? #13

Open AntoineTurmel opened 4 years ago

AntoineTurmel commented 4 years ago

Is it possible to use Animal Crossing features ?

theogravity commented 4 years ago

Here's what I've found so far:

Base URL: https://web.sd.lp1.acbaa.srv.nintendo.net/api/sd/v1

Headers:

List AC Chracters tied to the account

Session cookie is required.

Method: GET Path: /users

Response format:

{
    "users": [{
                 // character id
        "id": string,
                 // character name
        "name": string,
                 // character passport image URL
        "image": string,
                 // island info
        "land": {
                         // island id
            "id": string,
                         // island name
            "name": string,
                         // not sure what this is, but the value was "2" for me at the time
            "displayId": number
        }
    }]
}
}

Get auth token

Method: POST Path: /auth_token

Response format:

{
        // opaque value
    "token": string,
       // unix timestamp, looks like 1 hr expiry is set
    "expireAt": number
}

Get user passport

Method: GET Path: /users/:user_id/profile?language=en-US

Response:

{
        // unsure, was 30723
    "mVer": number,
         // en-US was my value
    "mLanguage": string,
        // character name
    "mPNm": string,
        // your birthdate set in game
    "mBirth": {
        "month": number,
        "day": number
    },
        // your passport title
        // mine is "Untossable Trash"
    "mHandleName": string,
        // the custom comment you set in your passport
    "mComment": string,
        // unsure what this is, but it was set to true for me
    "mIsLandMaster": bool,
        // unsure what this is, but it was set to 2020-3-23
    "mTimeStamp": {
        "year": number,
        "month": number,
        "day": number
    },
        // unsure what this is, but the value is empty
    "mMyDesignAuthorId": "string
        // passport profile pic
    "mJpeg": string,
        // unsure, was an 0xYYYYYYYYYYYYYY value
    "contentId": string,
         // checksum?
    "digest": string,
    "createdAt": number,
         // name of your island
    "landName": string
}

Get island data and island inhabitants

Method: GET Path: /lands/:land_id/profile?language=en-US

Response:

{
        // unsure, was 30723
    "mVer": number,
        // en-US
    "mLanguage": string,
       // unsure, was 2
    "mVRuby": number,
       // island name
    "mVNm": string,
         // island native fruit
    "mFruit": {
                 // fruit id?
        "id": number,
                 // fruit name - mine was "Peaches"
        "name": string
    },
         // animal villagers
    "mNormalNpc": [{
        "name": "Renée",
        "image": "...",
        "birthMonth": 5,
        "birthDay": 28
    }],
        // active non-npcs on the island?
       // the only entry was my char, but I did not have any visitors at this time
    "mVillager": [{
                 // my character's name
        "mPNm": string,
                 // my character's passport photo
        "mJpeg": string,
                 // character id
        "userId": number
    }]
}
frozenpandaman commented 4 years ago

cc @Thulinma who will find the above helpful :)

Thulinma commented 4 years ago

perks up Oooh, useful indeed! Has anyone taken a look at the pattern upload stuff yet?

theogravity commented 4 years ago

Here are some other endpoints that I noticed were different from the Splatoon 2 one:

Base Url: https://api-lp1.znc.srv.nintendo.net

Register Device

edit: There's a reference for this endpoint already:

https://github.com/ZekeSnider/NintendoSwitchRESTAPI/blob/master/SwitchBlueprint.md#register-device-v1notificationregisterdevice

Get web service token v2

Headers:

Method: POST Path: /v2/Game/GetWebServiceToken

Input:

{
    "parameter": {
                 // game id?
        "id": number,
                 // registration token from /v1/Notification/RegisterDevice
        "registrationToken": string,
                 // not sure how it's generated, value is in form of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
        "requestId": string,
                 // timestamp in ms when the request is to be made?
        "timestamp": number,
                 // unsure, some kind of checksum?
                // noticed its also found in /v1/Account/Login input, but the value is different
        "f": string
    }
}

For the "f" param - see this issue on what it is - the method of generation may differ compared to what is done with Splatoon, though:

https://github.com/ZekeSnider/NintendoSwitchRESTAPI/issues/6

Response:

{
    "result": {
                 // JWT value
        "accessToken": string,
                 // expires in seconds, was 7200
        "expiresIn": number
    },
         // some kind of id used for logging maybe?
    "correlationId": string,
         // status value was 0
    "status": number
}
Thulinma commented 4 years ago

Ooooh. They left sourcemaps in. You can see the entire source code. 🤤

Thulinma commented 4 years ago

I will leave this here for others to play with. BlancoClient.txt

frozenpandaman commented 4 years ago

cc @cgbuen as well (you had reached out to me about this in part)

cgbuen commented 4 years ago

For the "f" param - see this issue on what it is - the method of generation may differ compared to what is done with Splatoon, though

Everything up to and including GetWebServiceToken is fortunately exactly the same with Splatoon. The way it gets used once you get to the ACNH-specific address (web.sd.lp1.acbaa.srv.nintendo.net) is a bit different though.

A few notes for what I had found (particularly about auth / passport / keyboard):

  1. It's more appropriate now than ever to use @frozenpandaman 's s2s / Nexus's flapg to gather your WebServiceToken, which would be used to refresh the ACNH-specific access token (from the auth_token endpoint), since it expires every 2 hours. (I say this as opposed to the option of using an MitM proxy to pick off the access token, as I used to for Splatoon's iksm cookie, since its 3-day expiration was seldom enough for me.)
  2. There's a tiny gotcha in the passport endpoint data:
    • /api/sd/v1/users contains user IDs + island IDs
    • /api/sd/v1/lands/${islandId}/profile contains island info, including the list of user IDs
    • /api/sd/v1/users/${userId}/profile contains user info, but not the island ID that the user belongs to
  3. The keyboard is pretty interesting:
    • In the game and in the app, it appears that there are validations to ensure a "fluid" max character limit, i.e. your message has to literally look like it fits in the in-game / in-app keyboard message boxes (given that the ACNH fonts used are not monospace). However, this validation is only on the front end - so if you're using the POST endpoint for it, the hard max is actually 32 (it responds with an error if you go over). Meaning there are certain cases where you can actually have "longer" messages than what's allowed in-game/in-app.
    • For example, you can only type in "123456789012345678901234" (length 24) in-game/in-app, but you can actually POST "12345678901234567890123456789012" (length 32) programmatically.. what ends up happening in-game is that it condenses/squishes the text so that the message fits inside the message box.
    • Odd symbols will respond with a success (so long as the message length is <= 32), some of which will even display fine on-screen. I've even tried that creepy Zalgo text and nothing fully broke (still got a successful response), but it came on-screen as mostly question marks and line breaks that pushed the question marks outside of the message box.
    • There are in-game moments when you POST keyboard data and you won't see a speech bubble and instead get a no-keyboard symbol in the upper left, but this was evident even non-programmatically (e.g. you can just try sending an app message when exiting through a doorway). It should still appear in your in-game message history though.
  4. Personally haven't touched any of the other app features (best friends, patterns, etc.) yet, but the BlancoClient.txt file that @Thulinma posted above looks helpful.
  5. Here are my resources:
theogravity commented 4 years ago

I'm really stoked that this thread has gotten so many contributions in such a short period of time! Thanks everyone.

Re: GetWebServiceToken

For GetWebServiceToken, the interface and route is is different.

According to this: https://github.com/ZekeSnider/NintendoSwitchRESTAPI/blob/master/Splatoon2Blueprint.md#-get-homepage-get

Splatoon calls /v1/Game/GetWebServiceToken

But, AC is calling /v2/GameGetWebServiceToken with a different input.

Unless you mean it's still valid to call the v1 endpoint and use the token value for the subsequent calls

cgbuen commented 4 years ago

@theogravity It looks like that documentation may not be up-to-date (blame/history shows those sections were written in mid-2017).

The app currently (at the time of this writing) calls /v2/Game/GetWebServiceToken for both Splatoon and ACNH, with the following request body:

{
  id: [identifier for either Splatoon or ACNH as it appears from /v1/Game/ListWebServices],
  registrationToken: [value generated by app; corresponds with "p1" from 2nd flapg "app" call],
  timestamp: [value generated by app; corresponds with "p2" from 2nd flapg "app" call, which was passed through as an input into the flapg call],
  requestId: [value generated by app; corresponds with "p3" from 2nd flapg "app" call, which was passed through as an input into the flapg call],
  f: [value generated by app; corresponds with "f" from 2nd flapg "app" call]
}
xSke commented 4 years ago

Played around with this a bit - seems like they're pretty solid at authorization. You can only access your own or your best friends' passport/profile data, and you can only access your own island data. Your friends' island IDs are listed in the /friends endpoint, but looking them up gets you a 403.

As for those APIs:

GET https://web.sd.lp1.acbaa.srv.nintendo.net/api/sd/v1/friends

{
  "friends": [{
    "userId": "[ID of friend, this CAN be looked up at /users/<id>/profile]",
    "name": "[name of friend]",
    "image": "[URL to passport photo]",
    "land": {
      "id": "[ID of their island, this can't be looked up]",
      "name": "[name of their island]",
      "displayId": 2
    }
  }, { ... }]
}

This will only return "best" friends, not your full friend list. Unsure what land.displayId is, it's 2 for every friend on my end too.


GET https://web.sd.lp1.acbaa.srv.nintendo.net/api/sd/v1/friends/presences

{
  "presences": [{
    "userId": "[user ID of friend]",
    "state": 2
  }]
}

"State" here is the friend's online status - 1 is online, 2 is away, 0 is offline (but offline friends aren't included in the response).

Both require Authorization: Bearer <token> header, with the token from /auth_token. No HTTP bodies or any other query parameters.

xSke commented 4 years ago

Here's a working example of a Python script that hits all of the above APIs and prints information it can access, going through the entire login process automatically given an OAuth redirect URL: https://gist.github.com/xSke/8a4f06f9499a17b3e28cedfc094f57ca

frozenpandaman commented 4 years ago

@xSke Looks great, nice! To answer your comment there:

# I'm not entirely sure what this API does but it gets you a code that you need to move on.

You can find the documentation here: https://github.com/frozenpandaman/splatnet2statink/wiki/api-docs

As splatnet2statink is open-source, when the NSO app became necessary to emulate via an Android server (which NexusMine's flapg API is used for interacting with), we thought it'd be best to keep any sensitive hash-generation functionality (originally done on Nintendo's end) behind an API for the sake of privacy/security. So now the two APIs are used in conjunction. :)

We originally developed these for Splatoon 2 (plus, this was the only game originally integrated with the NSO app) but I'm fine with usage for cool ACNH stuff as well (but it might be helpful to have users specify which service/game you're using it for now, hmm… maybe just another optional parameter would be best for backwards compatibility). I can reach out to NexusMine about this as well (and link this thread) just as a heads up depending on what people intend to build with this.

xSke commented 4 years ago

@frozenpandaman Can you explain what that hash your API generates is for? On the app's end it goes directly from the token/request ID/timestamp to the f parameter and doesn't involve an intermediate step, how come the hash is necessary, and how come it can't be generated locally rather than through your API?

Also, do you know what progress has been made on understanding f parameter generation in the app (libvoip.so/gen_audio_h)? I'm messing with it myself and it's... a tough one, for sure. Could you just run the function in isolation without pulling in the rest of the app?

giraffesyo commented 4 years ago

Hi guys, I'd love to get involved in any of the projects you have in mind for ACNH. If you are working on something and need additional help lets get in contact!

xSke commented 4 years ago

I'm considering integrating my findings in a Discord bot, but the auth API being like it is makes that impractical, since you'd need each user to log in on their own -> hitting s2s/flapg a LOT + adding some major privacy concerns giving a central server access to everyone's login tokens. Would also like some way to access Dodo code data but as far as I can tell that's through their console-bound matchmaking APIs, and I don't have a hacked Switch to dump client certificates/keys from (and I wouldn't dare, either...).

frozenpandaman commented 4 years ago

@xSke

Can you explain what that hash your API generates is for? […] how come it can't be generated locally rather than through your API?

It's to pass to the flapg API which takes it as a header. I'm not exactly sure how NexusMine's flapg API is set up (i.e. whether the hash header is something NexusMine is requiring to prevent unauthorized requests to the Android server they're running, or if it's something originally done in one of the steps in-app by Nintendo) but to prevent abuse – because of the open-sourced nature of splatnet2statink – the hashing algorithm is kept private and not done locally (which NexusMine recommended in our original conversations early last year), thus where the call to the s2s API comes in.

do you know what progress has been made on understanding f parameter generation in the app

We gave up a year and a half ago or whatever when that big NSO app update came and complicated things a ton more and made it incomprehensible to me and the other people involved who were looking into this, trying to reverse engineer the app and all that – which is what eventually gave rise to NexusMine creating an Android server to run the NSO app originally for their own Splatoon-related iOS app (which s2s now uses too for cookie generation). However the NSO app works now (f was previously just an HMAC generated using a private key in the app, now it's more complicated), even if you did figure it out, Nintendo obviously doesn't want to make that public (and would probably rather not have us doing all this in the first place…) hence the flapg API is just a means to the same end, of being a step in the process of being able to generate cookies for users.

I'm considering integrating my findings in a Discord bot

For Splatoon at least, allowing a centralized Discord bot to be able to access users' battles directly from the app data seems impractical (but scraping stat.ink is good, and that's partially the point of s2s as a script!) but some people have set it up to integrate with their accounts using Rich Presence, i.e. to display last game played or whatnot.

hitting s2s/flapg a LOT + adding some major privacy concerns giving a central server access to everyone's login tokens.

The final "login token" cookies (sort of a misnomer here, they just provide access to what you see via the app, not your Nintendo account or anything), e.g. iksm_session in the case of Splatoon, are returned by Nintendo, not any of our APIs. No "central server" or anyone has access to any cookies, only you and the Nintendo.com endpoint that returns it to you. See the flowchart (slightly outdated but the gist is the same) in the s2s API docs. The only thing I or the flapg API could potentially log (and don't), besides timestamps or completely random UUIDs or whatever, is id_token, which isn't identifying information anyway – just a random jumble of characters provided by Nintendo at an earlier step…

xSke commented 4 years ago

Not particularly interested in Splatoon stuff myself as I don't even own the game, I'm more focused on Animal Crossing atm.

The goal of my app would be to have a clear path from "Login in with Nintendo Account" (OAuth) -> account info + AC:NH island stuff displayed in-bot, meaning it'd need to go through every login step server-side. If users have to dig up mitmproxy to extract their login tokens, that'd immediately rule out 99.5% of potential users, hence me saying it's probably not super practical in the first place. The privacy issues would then be on my end, since my bot has to handle everyone's Nintendo account tokens. Not a big deal in practice due to the OAuth scopes limiting access to anything but basic information, but probably enough for users to get paranoid and accusatory (have had that happen before...). I could theoretically do it now, but I'd rather not while your/flapg's APIs are still a link in the chain. Unsure how many users something like that would get, but it could easily be a lot more than is reasonable for y'all to be expected to handle.

Also, Nintendo's servers getting a lot of different login requests from the IP would probably flag something on their end, which adds another pebble to the "this is a bad idea" basket :)

frozenpandaman commented 4 years ago

Yeah, I'm just mentioning Splatoon because that's what all existing scripts and services and whatnot were created for, the background I'm approaching it from (I don't own ACNH), and AFAIK the login process here is like 95% the same.

Doing everything server-side makes sense and would be inevitable (though users would have to place some trust there, as you said re: privacy issues) for a bot or a central service, yeah. It's not dead easy, but a lot easier than mitmproxy: users who have just wanted their cookies in the past – even if not using the script, e.g. for various other projects like Discord's Rich Integration, or for users without smartphones wishing to access NSO app services from their browser – can just run s2s and grab their cookie from config.txt which they can then use for whatever other purposes. I'm not sure how they behave for ACNH, and it seems extremely variable for Splatoon (perhaps based on play history/usage or what), but cookies can last anywhere from a couple days to… apparently indefinitely, so hopefully no need to generate them every time the service gets used or something.

I'm not sure what we can expect to handle at this point – all good so far, though, including with the doubling in all requests recently due to some required changes in the script with the latest app update – but I'd say go ahead and start building whatever cool services that ACNH functionality now being in the NSO app may enable (e.g. type in-game messages from your computer, idk, again i don't have the game but it'd be cool to look into if i did). Like, hopefully the current/ongoing setup wouldn't be any bottleneck or cause to not; if users have to manually enter their cookie then so be it (it's not that hard to get, and this is all sort of niche development anyway so hopefully people have the motivation if they're seeking out these things in the first place).

AntoineTurmel commented 4 years ago

What tokens can be stored to avoid login to Nintendo profile ?

dodocodes commented 4 years ago

I'm also interested in how to lookup Island information from dodo code. If anyone has a working example, I'd love to see it!

This may be useful for someone: image

xSke commented 4 years ago

@dodocodes I found this not too long ago: https://github.com/Kinnay/NintendoClients/blob/master/example_animalcrossing.py Although it requires a hacked Switch to extract the certificates and keys, and there's a risk of getting console-banned. I've not tried it myself as my Switch is v2 and stock.

Unsure what those strings are referring to, they look similar to the app APIs described above but not entirely identical - might be on the .hac. domain if this is a dump from the actual game binary (any strings in there ending with nintendo.net?). Would probably need some more information on authentication, headers, login, etc. Where is this from?

dodocodes commented 4 years ago

The screenshot above is from the latest main binary for 1.1.4. Thanks for that link!

xSke commented 4 years ago

What tokens can be stored to avoid login to Nintendo profile ?

@AntoineTurmel You can store the session_token for up to 2 years, and reuse it for /api/login calls every time. The id/access_tokens have an expiry of only 15 minutes, though.

Alternatively, the Switch API access tokens (from /v1/Account/Login) last for 2 hours, as do the game-specific web service tokens. But I'd recommend just saving the session_tokens and going from there.

theogravity commented 4 years ago

@xSke I've managed to successfully get the island data using the dodo code via the example_animalcrossing.py script, but the journey to be able to do it is not for the faint of heart.

I might consider doing a write-up sometimes about how to do it, but it was a very lengthy and time-consuming process that requires a jailbroken switch.

image

I can sum it up as:

Although the API calls for user login is REST-based, the actual communication protocol to the nintendo servers is a binary wire format described on the wiki where that script is hosted. Building your own client would be a very difficult task that you should work with the NintendoClients library directly.

Then there's the island data itself - part of it is utf16-le encoded from what the example script offered, and there's other parts that I'm still trying to decipher. I managed to get out the character name, and I think I can also get native fruit data with enough sample data...

frozenpandaman commented 4 years ago

FWIW, some URLs accessible from within the app: https://twitter.com/barley_ural/status/1241450746568011776

FezVrasta commented 4 years ago

Did anyone manage to validate dodo codes without having to authenticate every time?

redpwilliams commented 4 years ago

I'm curious if any we're able to access the catalog. Please @ me if you have any ideas on this

xSke commented 4 years ago

I'm curious if any we're able to access the catalog. Please @ me if you have any ideas on this

As far as I can tell, none of that is network-synced, and it's all just stored on the device.

carrotcn commented 3 years ago

@xSke I've managed to successfully get the island data using the dodo code via the example_animalcrossing.py script, but the journey to be able to do it is not for the faint of heart.

I might consider doing a write-up sometimes about how to do it, but it was a very lengthy and time-consuming process that requires a jailbroken switch.

image

I can sum it up as:

  • dumping the sysnand
  • dumping the animal crossing encryption ticket (I believe this needs to be from a copy that you've paid for)
  • extracting the console encryption keys
  • decrypting the sysnand with the console enc keys
  • decrypting the USERINFO block in sysnand
  • decrypting the SYSTEM block in sysnand that contains the account data
  • extracting the SYSTEM data to a set of directories + files
  • finding the right file that represents the user account data in the block data
  • extracting the account data file to a set of directories + files
  • extracting the user id / pass (it's not your nintendo id / pass here) from the user account file using a hex editor
  • use the user id / pass, console keys, ac keys to make the API calls necessary to get the island data for the given dodo code

Although the API calls for user login is REST-based, the actual communication protocol to the nintendo servers is a binary wire format described on the wiki where that script is hosted. Building your own client would be a very difficult task that you should work with the NintendoClients library directly.

Then there's the island data itself - part of it is utf16-le encoded from what the example script offered, and there's other parts that I'm still trying to decipher. I managed to get out the character name, and I think I can also get native fruit data with enough sample data...

Thanks for enlightening me buddy. I managed to get the code to work following your instructions. I am listing the steps in detail for the benefit of others.

1. Download the switch homebrew package. https://www.sdsetup.com/console?switch In Pre-configured bundle, download the "recommended defaults" 2. Extract the downloaded zip archive from step #1. Copy all files and folders under folder "sd" into the root directory of your switch's SD card. 3. Download the injector https://github.com/eliboa/TegraRcmGUI/releases 4. Execute TegraRcmGUI.exe. For first-time user go to Settings tab and click on Install Driver. 5. Connect switch to your PC with a USB cable. Start the console in RCM mode (short pin 10 - the one closest to the back of the console - on the right joycon rail, to ground - the cooler fin for example, at the same time hold volume + button and press the power button) 6. Once in RCM mode, in injector you will see a GREEN icon. Select the file hekate_ctcaer_5.3.0.bin in payloads folder of extract from step #1. Press the Inject button. 7. In Hekate, dump the sysnand. Navigate to Tools > Backup eMMC > eMMC BOOT0 & BOOT1 and let it do its thing. Wait for the process to complete. When it's completed, you now have a backup/[8 Character NAND id]/restore folder on your sd card. 8. Merge the archives named rawnand.bin.00 thru 14 with below command in CMD: copy /b rawnand.bin.00 + rawnand.bin.01 + rawnand.bin.02 + rawnand.bin.03 + rawnand.bin.04 + rawnand.bin.05 + rawnand.bin.06 + rawnand.bin.07 + rawnand.bin.08 + rawnand.bin.09 + rawnand.bin.10 + rawnand.bin.11 + rawnand.bin.12 + rawnand.bin.13 + rawnand.bin.14 rawnand.bin 9. Dump the BIS keys. https://switchtools.sshnuke.net Once again boot into RCM mode, then use injector to load biskeydump.bin. Execute to get the BIS KEYS. 10. Download HacDiskMount https://switchtools.sshnuke.net Launch HacDiskMount with Admin right, open rawnand.bin. 11. Extract the decrypted PRODINFO.bin Double click on PRODINFO. Paste in the BIS KEY string from step #9. Extract PRODINFO.bin 12. Extract the save file 8000000000000010 In HacDiskMount (step 10) double click on SYSTEM. Paste in the BIS KEY string from step #9. Mount it as virtual drive. First-time user please install the driver first (click the install button). In the virtual drive open folder "save" and make a copy of 8000000000000010. 13. Download hactoolnet https://github.com/Thealexbarney/LibHac/releases 14. Extract BAAS user/password Command: hactoolnet -t save --outdir 8000000000000010-extracted /path/to/system.img-mountpoint/save/8000000000000010 In folder "8000000000000010-extracted" get .dat file from \su\baas folder. In case there are multiple .dat files in \su\baas, identify the desired user by cross-checking the filename with su\avatars Retrieve BAAS credential with below Python program: with open('D:\\xxxxxxxx.dat', 'rb') as f: f.seek(0x20) print('BAAS user ID:', hex(int.from_bytes(f.read(8), byteorder='little'))) print('BAAS password:', f.read(40).decode('ascii')) 15. Extract the prod and title keys Once again boot into RCM mode, then use injector to load Lockpick_RCM.bin in payloads folder of extract from step #1. Execute to get the prod.keys and title.keys under SD card \switch folder. 16. Download NXDumpTool https://github.com/DarkMatterCore/nxdumptool/releases Copy the .nro of NXdumptool to the switch folder on your sd card. Verify the existence of prod.keys file under \switch folder of your SD card. Launch into Sys CFW via Hekate. Open the Homebrew Menu from the Album, and open nxdumptool. Select Dump installed SD card / eMMC content, then select ACNH (base). Look for the base ticket, not an update ticket of ACNH. Do NOT "remove console specific data" from the ticket. You should be able to see the .tik ticket file under folder \switch\nxdumptool\Ticket in your SD card now. 17. Check-out the repo https://github.com/Kinnay/NintendoClients in repo folder execute in CMD: pip3 install . You will probably need the C++ runtime if error occurred during the installation of dependent libraries. Make a copy of example_animalcrossing.py. Update the following constant at the top of the code: 1. BAAS credential 2. Path of prod.keys 3. Path of PRODINFO.bin 4. Path of .tik file 5. DODO code to be checked Time for smoke test. For python errors from the library just try figuring it out.
theogravity commented 3 years ago

@carrotcn you got it! As stated before, definitely not for the faint of heart.

Also concerned about running this as a public service as you could risk the acct you're using to call the nintendo mm service getting banned as you're making proxy calls on behalf of the user using that account

carrotcn commented 3 years ago

I am now actually curious as to how websites like turnip.exchange manage to detect the island name and host name via DODO code you put in when creating listing on their website. I would guess it should be something similar but then just imagine the number of queries getting triggered from those sites...

theogravity commented 3 years ago

@carrotcn My guess is that they create multiple dedicated account for this purposely, which probably uses a shared nintendo switch online family account. The island name and host name is actually in the response payload - edit the python script a little to interpret some of the initial bytes as utf-16 I think.

Thulinma commented 3 years ago

@carrotcn As far as I've understood from one of the devs behind that website, they have "special connections" that make it possible. My interpretation of that statement is that they know somebody "on the inside" that lets their system through and/or put them on some sort of whitelist to prevent banning. After all, usage at the scale they are doing would not go unnoticed, and would almost certainly result in banned accounts within a few days at most. (This is also why we chose not to even try implementing support for Able Sisters codes on acpatterns.com - we doubt we'd get away with it.)

theogravity commented 3 years ago

@carrotcn As far as I've understood from one of the devs behind that website, they have "special connections" that make it possible. My interpretation of that statement is that they know somebody "on the inside" that lets their system through and/or put them on some sort of whitelist to prevent banning. After all, usage at the scale they are doing would not go unnoticed, and would almost certainly result in banned accounts within a few days at most. (This is also why we chose not to even try implementing support for Able Sisters codes on acpatterns.com - we doubt we'd get away with it.)

I actually interpreted that as we figured out how to use the MM protocol when I read it back then.

Thulinma commented 3 years ago

@theogravity I'm not talking about the statement on the website itself. I spoke with one of the devs and while they could not give me any real information because of an NDA, it was clear there was some sort of permission from somewhere/someone. I asked if whoever arranged this could possibly do something for us too. They said they'd ask, but I never heard back after that so I'm guessing the answer was probably "no".

theogravity commented 3 years ago

@theogravity I'm not talking about the statement on the website itself. I spoke with one of the devs and while they could not give me any real information because of an NDA, it was clear there was some sort of permission from somewhere/someone. I asked if whoever arranged this could possibly do something for us too. They said they'd ask, but I never heard back after that so I'm guessing the answer was probably "no".

I'm not surprised - it's their secret "sauce" that prevents any competition from happening.

mathewthe2 commented 3 years ago

I'm curious if any we're able to access the catalog. Please @ me if you have any ideas on this

With the new catalog feature, we can access the user's catalog with the following endpoints:

GET /api/sd/v1/catalog_items?language=ja-JP

GET /api/sd/v1/catalog_items/latest

GET, PUT, DELETE /api/sd/v1/catalog_items/favorites

You can see more in the BlancoClient.ts file when you access the base url https://web.sd.lp1.acbaa.srv.nintendo.net/

BlancoClient.txt

TomCasavant commented 2 years ago

I know this is a longshot, but I'm messing around w/ the ACNH api rn and running into a wall at actually logging into the ACNH api (authenticating the user and everything else up to that point is working fine), but for requests made to https://web.sd.lp1.acbaa.srv.nintendo.net/api/sd/v1/auth_token I'm getting a 401 error with the response: (<Response [401]>; { "code": "4003" })

which I think means they've updated what is needed to authenticate the request, but if anyone has any thoughts that would be wonderful

EDIT/UPDATE: Spent a few more hours looking around and found this https://github.com/Jetsurf/jet-bot/blob/master/modules/nsotoken.py, I implemented my auth_token method in the same way they did and it worked flawlessly

frozenpandaman commented 1 year ago

@TomCasavant FYI that file is largely based on https://github.com/frozenpandaman/splatnet2statink/blob/master/iksm.py (like, it seems the file is just a modified version of mine with all the sql & asyncio stuff added in – fwiw)

TomCasavant commented 1 year ago

@TomCasavant FYI that file is largely based on https://github.com/frozenpandaman/splatnet2statink/blob/master/iksm.py (like, it seems the file is just a modified version of mine with all the sql & asyncio stuff added in – fwiw)

Oh, perfect. I didn't see yours when I was searching before. Thanks!