project-serum / serum-js

JavaScript client library for interacting with the Project Serum DEX.
82 stars 33 forks source link

Question on how to create a 'new Account()' from the id.json #23

Closed rudijs closed 4 years ago

rudijs commented 4 years ago

Hi,

I'd like to get all my open orders from a market on Serum.

I've been able to connect and list the bids/asks, but now I want to see my open orders.

I do have an open order on the FTT/USDC market but my code returns an empty array.

I've created a wallet using sollet.io and placed several orders that have filled using the Dex UI.

So working backwards from there, I've created the ~/.config/solana/id.json file by using 'solana-keygen recover' and enter the sollet.io wallet seed phrase and password.

Then use the Array from id.json as input to 'new Account()', but my actual open orders are not listed in the output (empty array of results when there is one open order on the dex)

I hope I explained that OK.

Where am I going wrong?

Here's some code I'm hacking around with:

import { Connection, Account } from "@solana/web3.js"
import { MARKETS, Market } from "@project-serum/serum"
import * as fs from "fs"

// create the ~/.config/solana/id.json by using 'solana-keygen recover' and enter the sollet.io wallet seed phrase and password
const solanaId = JSON.parse(fs.readFileSync("/home/rudi/.config/solana/id.json", { encoding: "UTF-8" }))
// console.log(solanaId)

const fttUsdc = MARKETS.filter((item: any) => item.name === "FTT/USDC")[0]
// console.log(fttUsdc)

let connection = new Connection("https://api.mainnet-beta.solana.com/")

let owner = new Account(solanaId)

async function main() {
  let market = await Market.load(connection, fttUsdc.address, undefined, fttUsdc.programId)
  // console.log(market)

  // Retrieving open orders by owner
  // console.log(owner.publicKey, owner.secretKey)
  let myOrders = await market.loadOrdersForOwner(connection, owner.publicKey)
  console.log(myOrders)
}

main()
  .then((res) => console.log(res))
  .catch((err) => console.log(err))

Here's a screen cap of the open order under my account on the dex:

Screenshot from 2020-09-21 14-24-50

rudijs commented 4 years ago

Hmm ... When I use the same seed phrase and password that I use for the sollet wallet, the recovered pubkey is not the same

solana-keygen recover
[recover] seed phrase:
[recover] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue:
Recovered pubkey `[not-the-same-as-sollet.io]`. Continue? (y/n):

When using solana-keygen recover it should produce the same pubkey as my sollet wallet when I use the same seed phrase and password right?

rudijs commented 4 years ago

It's the same for solana-keygen pubkey ASK .. entering the seed phrase and password that I use for the sollet wallet produces and different public key output

solana-keygen pubkey ASK
[pubkey recovery] seed phrase:
[pubkey recovery] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue:
Enter same passphrase again:
rudijs commented 4 years ago

OK, I'm sure I've done this the hard way but I've figured out a method that works.

For posterity and anyone else looking for the same thing here's what I have (using Typescript):

Create a function to return an Account object from the seed phrase only used to create a wallet on sollet.io

import * as bip32 from "bip32"
import * as bip39 from "bip39"
import { Account } from "@solana/web3.js"
import nacl from "tweetnacl"

export const wallet = async (mnemonic: string) => {
  const seed = await bip39.mnemonicToSeed(mnemonic)
  // console.log(seed)

  const walletIndex = 0
  const accountIndex = 0

  const derivedSeed = bip32.fromSeed(seed).derivePath(`m/501'/${walletIndex}'/0/${accountIndex}`).privateKey
  // console.log(derivedSeed)

  const account = new Account(nacl.sign.keyPair.fromSeed(derivedSeed!).secretKey)
  // console.log(account.publicKey.toString())
  // console.log(account.secretKey.toString())
  return account
}

Now use that function in some code to query open orders for the FTT/USDC market on Serum Dex:

import { Connection } from "@solana/web3.js"
import { MARKETS, Market } from "@project-serum/serum"
import { wallet } from "./wallet"

if (!process.env.MNEMONIC) throw "Missing required Env var: MNEMONIC"

const fttUsdc = MARKETS.filter((item: any) => item.name === "FTT/USDC")[0]
// console.log(fttUsdc)

let connection = new Connection("https://api.mainnet-beta.solana.com/")

async function main() {
  let owner = await wallet(process.env.MNEMONIC!)

  let market = await Market.load(connection, fttUsdc.address, undefined, fttUsdc.programId)
  // console.log(market)

  // Retrieving open orders by owner
  // console.log(owner.publicKey.toString())
  let myOrders = await market.loadOrdersForOwner(connection, owner.publicKey)
  // console.log(myOrders)

  for (let order of myOrders) {
    console.log(order)
  }
}

main()
  .then((res) => console.log(res))
  .catch((err) => console.log(err))