GenesysGo / shadow-drive

Apache License 2.0
70 stars 22 forks source link

Asks for a Private Key when uploading to an existing storage account #55

Closed numisman closed 2 years ago

numisman commented 2 years ago

Hello,

I am trying to use the SDK to upload a file to my Shadow Drive. I have my wallet, the drive, find the correct account, and then I attempt to upload my file as a ShadowFile:

const pngFileBuffer = fs.readFileSync(`${__dirname}/../output/0.png`);
const pngShadowFile: ShadowFile  = {name: '0.png', file: pngFileBuffer}
const pngFileUploadResult = await drive.uploadFile(shadowAccount.publicKey, pngShadowFile, "v2" );

And it responds with

}
Error: TypeError: Cannot read properties of undefined (reading 'secretKey')
    at ShdwDrive.<anonymous> (upload-file.ts:93:27)
    at Generator.next (<anonymous>)
    at upload-file.js:8:71
    at new Promise (<anonymous>)
    at __awaiter (upload-file.js:4:12)
    at ShdwDrive.uploadFile (/upload-file.js:29:12)
    at shadowUtils.ts:33:41
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
Waiting for the debugger to disconnect...

I am not sure how to go about debugging this - can you point me in the correct direction? Short of that, if you have a working example of uploading files through Node, I'd be very happy to see it.

Thanks!

tracy-codes commented 2 years ago

Can you please share more of the code you're using? Including things like initializing they drive object and how you're pulling in your wallet would be very helpful here.

Along with that, are you using this with nodejs or a browser environment?

numisman commented 2 years ago

Thanks for quickly responding! Sure:

Firstly, I'm in a Node.js environment (v18 to be exact) I am pulling in a file wallet. Here's how I'm doing it:

const decodedKey = new Uint8Array(
    JSON.parse(
        fs.readFileSync(`${__dirname}/../../exchanger_support_files/SHADOW_WALLET.json`).toString()
    ));
const wallet = Keypair.fromSecretKey(decodedKey);

const drive = await new ShdwDrive(conn, wallet).init();
const shadow = await drive.getStorageAccounts("v2");

const shadowAccount = shadow.find((thisAcct) => {
                                       let sAcctId = thisAcct.account.identifier;
                                       if (sAcctId === SHADOW_ACCOUNT_ID) {
                                          return thisAcct
                                       }
                                  });

And it appears that the function you have to upload - in @shadow-drive/sdk/dist/methods/upload-file, on line 80 - it's expecting the wallet object to have a "payer" member - but this method of getting the wallet doesn't provide it.
image

Is there a better way of bringing in a wallet from a file system so that it'll work this way? I'd be happy to adjust that. I really do need to get this piece working pretty soon.

Thanks so much!

numisman commented 2 years ago

And I just tried removing the payer member and ran it, and it worked for me. I will attempt to add to my wallet object (if typescript will let me) the payer member with the child secret key to see if that does it. But I'm sure I won't be the only one to hit this as adoption continues (because the platform is so much better than anything else out there IMO)....so if you can handle it with a null check I think that could fix the issue.

tracy-codes commented 2 years ago

Instead of initializing your wallet with Keypair.from, you should do something like this:

import * as anchor from "@project-serum/anchor";
const decodedKey = new Uint8Array(
    JSON.parse(
        fs.readFileSync(`${__dirname}/../../exchanger_support_files/SHADOW_WALLET.json`).toString()
    ));
const wallet = new anchor.Wallet(decodedKey);

Where you're using the anchor javascript package to instantiate a new Wallet object.

The Keypair object from Solana's Web3.js package doesn't include the other necessary functions that the anchor client we use internally requires.

numisman commented 2 years ago

Thanks a bunch! Didn't think I'd need anchor here. I'll give it a shot and close the ticket if I'm all good!

numisman commented 2 years ago

THANK YOU SO MUCH!!!

Had to keep the keypair in there because the keypair is the correct parameter to anchor.Wallet(). Here's the correct wallet-getting code for anyone else struggling with it:

const decodedKey = new Uint8Array(
    JSON.parse(
        fs.readFileSync(`${__dirname}/../../exchanger_support_files/SHADOW_WALLET.json`).toString()
    ));

const keypair = Keypair.fromSecretKey(decodedKey);
const wallet = new anchor.Wallet(keypair);

After that, it works swimmingly!

Thanks again Tracy! I'll close this.