Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

secret.js does not appear to have Secp256k1Pen #138

Open
ChristianOConnor opened this issue Feb 12, 2023 · 3 comments
Open

secret.js does not appear to have Secp256k1Pen #138

ChristianOConnor opened this issue Feb 12, 2023 · 3 comments

Comments

@ChristianOConnor
Copy link

I am building a Secret NFT and I'm following this tutorial https://youtu.be/jRuSOos9ig4. I tried to deploy the NFT like this video narrator does around 31:12. I ran a the deploy-nft.js file which failed at this line:

const signingPen = await Secp256k1Pen.fromMnemonic(mnemonic).catch((err) => {
  throw new Error(`Could not get signing pen: ${err}`);
});

With this error:

TypeError: Cannot read properties of undefined (reading 'fromMnemonic')
    at main (C:\Users\nyusername\path\to\secret-nft-two\contract\deploy-nft.js:40:43)
    at Object.<anonymous> (C:\Users\nyusername\path\to\secret-nft-two\contract\deploy-nft.js:94:3)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Module._load (node:internal/modules/cjs/loader:827:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47

I imported Secp256k1Pen at the top of the file like this:

const {
  EnigmaUtils,
  Secp256k1Pen,
  SigningCosmWasmClient,
  pubkeyToAddress,
  encodeSecp256k1Pubkey,
} = require("secretjs");

The entire file incorporating the above code looks like this:

const {
    EnigmaUtils,
    Secp256k1Pen,
    SigningCosmWasmClient,
    pubkeyToAddress,
    encodeSecp256k1Pubkey,
  } = require("secretjs");
  const fs = require("fs");
  
  // Load environment variables
  require("dotenv").config();
  
  const customFees = {
    upload: {
      amount: [{ amount: "5000000", denom: "uscrt" }],
      gas: "5000000",
    },
    init: {
      amount: [{ amount: "500000", denom: "uscrt" }],
      gas: "500000",
    },
    exec: {
      amount: [{ amount: "500000", denom: "uscrt" }],
      gas: "500000",
    },
    send: {
      amount: [{ amount: "80000", denom: "uscrt" }],
      gas: "80000",
    },
  };
  
  const main = async () => {
    const httpUrl = process.env.__VITE_SECRET_REST_URL;
  
    // Use key created in tutorial #2
    const mnemonic = process.env.VITE_MNEMONIC;
  
    // A pen is the most basic tool you can think of for signing.
    // This wraps a single keypair and allows for signing.
    const signingPen = await Secp256k1Pen.fromMnemonic(mnemonic).catch((err) => {
      throw new Error(`Could not get signing pen: ${err}`);
    });
  
    // Get the public key
    const pubkey = encodeSecp256k1Pubkey(signingPen.pubkey);
  
    // get the wallet address
    const accAddress = pubkeyToAddress(pubkey, "secret");

    // 1. Initialize client
    const txEncryptionSeed = EnigmaUtils.GenerateNewSeed();

    const client = new SigningCosmWasmClient(
        httpUrl,
        accAddress,
        (signBytes) => signingPen.sign(signBytes),
        txEncryptionSeed, customFees,
    );
    console.log(`Wallet address=${accAddress}`);
  
    // 2. Upload the contract wasm
    const wasm = fs.readFileSync('my-snip721/contract.wasm');
    console.log('Uploading contract');
    const uploadReceipt = await client.upload(wasm, {})
        .catch((err) => { throw new Error(`Could not upload contract: ${err}`); });

    // Get the code ID from the receipt
    const { codeId } = uploadReceipt;
    const initMsg = {
        /// name of token contract
        name: process.env.CONTRACT_NAME,
        /// token contract symbol
        symbol: process.env.CONTACT_SYMBOL,
        /// entropy used for prng seed
        entropy: process.env.RANDOM_LOWERCASE_LETTERS_SEED,
        /// optional privacy configuration for the contract
        config: {
            public_owner: true
        },
    }
    const contract = await client
      .instantiate(
        codeId,
        initMsg,
        `My Snip721${Math.ceil(Math.random() * 10000)}`
      )
      .catch((err) => {
        throw new Error(`Could not instantiate contract: ${err}`);
      });
    const { contractAddress } = contract;
    console.log("contract: ", contract, "address:", contractAddress);
  };
  
  main().catch((err) => {
    console.error(err);
  });

And I run this file with node deploy-nft.js. Also according to my package.json file, I'm using "secretjs": "^1.6.13"

So why is it failing with this error? Is secret.js not properly exposing Secp256k1Pen?

@assafmo
Copy link
Member

assafmo commented Feb 12, 2023

Hi, this looks to be a very old secret.js code. Please read the current docs at https://github.com/scrtlabs/secret.js#readme, you can use Wallet to import your mnemonics.

@ChristianOConnor
Copy link
Author

Hi, this looks to be a very old secret.js code. Please read the current docs at https://github.com/scrtlabs/secret.js#readme, you can use Wallet to import your mnemonics.

Gotcha, I actually modified my code but I'm getting a new problem. I am trying to upload a build of this contract https://github.com/baedrik/snip721-reference-impl. I made this new upload script which I reassembled from this code: https://github.com/scrtlabs/SecretJS-Templates/blob/master/5_contracts/main.js. It looks like this:

const { Wallet, SecretNetworkClient } = require("secretjs");
const fs = require("fs");

// Load environment variables
require("dotenv").config();

const main = async () => {
  const wallet = new Wallet(process.env.VITE_MNEMONIC);

  // Create a connection to Secret Network node
  // Pass in a wallet that can sign transactions
  // Docs: https://github.com/scrtlabs/secret.js#secretnetworkclient
  const secretjs = new SecretNetworkClient({
    url: process.env.__VITE_SECRET_REST_URL,
    wallet: wallet,
    walletAddress: wallet.address,
    chainId: process.env.VITE_SECRET_CHAIN_ID,
  });
  console.log(`Wallet address=${wallet.address}`);

  // 2. Upload the contract wasm
  const wasm = fs.readFileSync('my-snip721/contract.wasm');
  console.log('Uploading contract');

  const tx = await secretjs.tx.compute.storeCode(
    {
      sender: wallet.address,
      wasm_byte_code: wasm,
      source: "https://github.com/baedrik/snip721-reference-impl",
      builder: "baedrik",
    },
    {
      gasLimit: 1_000_000,
    }
  );
  console.log(tx);

  const codeId = Number(
    tx.arrayLog.find((log) => log.type === "message" && log.key === "code_id")
      .value
  );
  console.log("codeId: ", codeId);

  // contract hash, useful for contract composition
  const contractCodeHash = (await secretjs.query.compute.codeHashByCodeId({code_id: codeId})).code_hash;
  console.log(`Contract hash: ${contractCodeHash}`);
};

main();

I get this error:

TypeError: Cannot read properties of undefined (reading 'find')

Notice that I'm logging tx which looks like this after I format it to json:

{
    "height": 0,
    "timestamp": "",
    "transactionHash": "LONG STRING HERE...",
    "code": 18,
    "codespace": "sdk",
    "info": "",
    "tx": {
        "@type": "/cosmos.tx.v1beta1.Tx",
        "body": {
            "messages": ["Array"],
            "memo": "",
            "timeout_height": "0",
            "extension_options": [],
            "non_critical_extension_options": []
        },
        "auth_info": { "signer_infos": ["Array"], "fee": ["Object"] },
        "signatures": [
            "ANOTHER LONG STRING HERE..."
        ]
    },
    "rawLog": "builder invalid: invalid request",
    "jsonLog": "undefined",
    "arrayLog": "undefined",
    "events": [],
    "data": [],
    "gasUsed": 822,
    "gasWanted": 0,
    "ibcResponses": []
}

arrayLog is undefined. So how do I get this snip 721 to upload?

@assafmo
Copy link
Member

assafmo commented Feb 12, 2023

If tx.code != 0 then the tx failed, then in rawLog you can see that you get the error builder invalid: invalid request. I think the builder field should be a docker image version, so maybe it's getting the wrong format? You can also just not pass this field

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants