From 88bde75d031c5f4fbf00fe0426f0de199d450019 Mon Sep 17 00:00:00 2001 From: rigwild Date: Fri, 2 Aug 2024 03:15:00 +0200 Subject: [PATCH] Allow selecting backend endpoint to hit, and adjust to latest API schema --- README.md | 11 +++--- src/NemeosBackendClient.ts | 44 +++++++++++++++++++---- src/NemeosSDK.ts | 5 +++ src/Pool/NemeosPoolBuyOpenSeaClient.ts | 17 ++++++--- src/Pool/NemeosPoolClient.ts | 4 +-- src/Pool/NemeosPoolDirectMintClient.ts | 12 +++++-- tests/test.mjs | 49 ++++++++++++++++++-------- 7 files changed, 107 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 7c59cf3..6695f58 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ const wallet = new ethers.Wallet(process.env.WALLET_PRIVATE_KEY, provider) const nemeosSdk = new NemeosSDK(wallet, { enableLogging: true, // Enable logging to the console - Optional, default: `true` + nemeosBackendEnvironment: NemeosSDK.NemeosBackendEnvironment.Production, // Optional, default: `Production` }) ``` @@ -68,6 +69,7 @@ const signer = await provider.getSigner() const nemeosSdk = new NemeosSDK(signer, { enableLogging: true, // Enable logging to the console - Optional, default: `true` + nemeosBackendEnvironment: NemeosSDK.NemeosBackendEnvironment.Production, // Optional, default: `Production` }) ``` @@ -81,6 +83,7 @@ const signer = await provider.getSigner() const nemeosSdk = new NemeosSDK(signer, { enableLogging: true, // Enable logging to the console - Optional, default: `true` + nemeosBackendEnvironment: NemeosSDK.NemeosBackendEnvironment.Production, // Optional, default: `Production` }) ``` @@ -148,7 +151,7 @@ const nemeosPoolClient = nemeosSdk.getNemeosPoolClient({ ```ts try { // Preview loan for Nemeos Pool `BuyOpenSea` mode - const nftId = 231 + const nftId = '231' const loanDurationDays = 61 const loanData = await nemeosPoolBuyOpenSeaClient.previewLoan(nftId, loanDurationDays) @@ -441,7 +444,7 @@ export type NftLivePriceDirectMintData = { ```ts try { // Start loan for Nemeos Pool `BuyOpenSea` mode - const nftId = 224 + const nftId = '224' const loanDurationDays = 90 const tx = await nemeosPoolBuyOpenSeaClient.startLoan(nftId, loanDurationDays) @@ -460,7 +463,7 @@ try { #### Retrieve a loan ```ts -const nftId = 224 +const nftId = '224' const loan = await nemeosPoolClient.retrieveLoan(nftId) ``` @@ -501,7 +504,7 @@ type Loan = { ```ts try { - const nftId = 224 + const nftId = '224' const tx = await nemeosPoolClient.payNextLoanStep(nftId) console.log('Paying next loan step success! Transaction hash:', tx.hash) diff --git a/src/NemeosBackendClient.ts b/src/NemeosBackendClient.ts index b2fdb18..4dad180 100644 --- a/src/NemeosBackendClient.ts +++ b/src/NemeosBackendClient.ts @@ -7,16 +7,40 @@ const extractHttpErrorMessageThenThrow = (error: any) => { throw new NemeosSDKError(extractHttpErrorMessage(error)) } +export enum NemeosBackendEnvironment { + Development = 'development', + Preprod = 'preprod', + Production = 'production', +} + export class NemeosBackendClient { - private static readonly ofetchClient = ofetch.create({ + private static ofetchClient = ofetch.create({ baseURL: - process.env.NODE_ENV === 'development' + process?.env?.NODE_ENV === NemeosBackendEnvironment.Development ? 'http://localhost:8000' - : process.env.NODE_ENV === 'preprod' + : process?.env?.NODE_ENV === NemeosBackendEnvironment.Preprod ? 'https://testnet-api.nemeos.finance' : 'https://api.nemeos.finance', }) + public static setEnvironment(env: NemeosBackendEnvironment) { + const baseURL = + env === NemeosBackendEnvironment.Development + ? 'http://localhost:8000' + : env === NemeosBackendEnvironment.Preprod + ? 'https://testnet-api.nemeos.finance' + : 'https://api.nemeos.finance' + + if (env !== NemeosBackendEnvironment.Production) { + console.log('[nemeos] NemeosBackendClient will use API at', baseURL) + } + NemeosBackendClient.ofetchClient = ofetch.create({ baseURL }) + } + + // + // ------------------------------ + // + public static async generateLoginSignature(metamaskSigner: ethers.Signer): Promise { const message = `Action: check_ownership ; Date: ${new Date().toISOString()}` return { @@ -62,24 +86,26 @@ export class NemeosBackendClient { // public static async fetchLivePriceBuyOpenSeaData( nftCollectionAddress: string, - nftId: number, + nftId: string, loanDurationDays: number, + borrowerAddress: string, ): Promise { return NemeosBackendClient.ofetchClient( `/nftCollections/${nftCollectionAddress}/protocolVariant/buyOpenSea/nftId/${nftId}/livePriceData`, { query: { loanDurationDays, + customerWalletAddress: borrowerAddress, }, }, ).catch(extractHttpErrorMessageThenThrow) } public static async fetchStartLoanBuyOpenSeaData( - borrowerAddress: string, nftCollectionAddress: string, - nftId: number, + nftId: string, loanDurationDays: number, + borrowerAddress: string, ): Promise { return NemeosBackendClient.ofetchClient( `/nftCollections/${nftCollectionAddress}/protocolVariant/buyOpenSea/nftId/${nftId}/startLoanData`, @@ -99,21 +125,23 @@ export class NemeosBackendClient { public static async fetchLivePriceDirectMintData( nftCollectionAddress: string, loanDurationDays: number, + borrowerAddress: string, ): Promise { return NemeosBackendClient.ofetchClient( `/nftCollections/${nftCollectionAddress}/protocolVariant/directMint/livePriceData`, { query: { loanDurationDays, + customerWalletAddress: borrowerAddress, }, }, ).catch(extractHttpErrorMessageThenThrow) } public static async fetchStartLoanDirectMintData( - borrowerAddress: string, nftCollectionAddress: string, loanDurationDays: number, + borrowerAddress: string, whitelistProof?: string[], ): Promise { return NemeosBackendClient.ofetchClient( @@ -355,6 +383,8 @@ export type NftStartLoanBuyOpenSeaData = { export type NftLivePriceDirectMintData = { nftFullLivePriceData: { + /** @example "231" */ + nextMintNftId: string /** @example "100000000000000000" */ mintPrice: string /** @example "0.1" */ diff --git a/src/NemeosSDK.ts b/src/NemeosSDK.ts index f9328e0..a6aff0c 100644 --- a/src/NemeosSDK.ts +++ b/src/NemeosSDK.ts @@ -4,6 +4,7 @@ import { NemeosPoolBuyOpenSeaClient } from './Pool/NemeosPoolBuyOpenSeaClient.js import { NemeosPoolDirectMintClient } from './Pool/NemeosPoolDirectMintClient.js' import { assertValidHexAddress } from './utils.js' import { NemeosPoolMode } from './constants.js' +import { NemeosBackendClient, NemeosBackendEnvironment } from './NemeosBackendClient.js' export const getBrowserProvider = (windowEthereum: ethers.Eip1193Provider) => { return new ethers.BrowserProvider(windowEthereum) @@ -17,9 +18,12 @@ export class NemeosSDK { options?: { /** Enable logging to the console - Optional, default: `true` */ enableLogging?: boolean + /** Nemeos Backend environment - Optional, default: `NemeosBackendEnvironment.Production` */ + nemeosBackendEnvironment?: NemeosBackendEnvironment }, ) { this.enableLogging = options?.enableLogging === undefined ? true : options.enableLogging + NemeosBackendClient.setEnvironment(options?.nemeosBackendEnvironment || NemeosBackendEnvironment.Production) } public getNemeosCustomerClient(): NemeosCustomerClient { @@ -51,4 +55,5 @@ export class NemeosSDK { } public static NemeosPoolMode = NemeosPoolMode + public static NemeosBackendEnvironment = NemeosBackendEnvironment } diff --git a/src/Pool/NemeosPoolBuyOpenSeaClient.ts b/src/Pool/NemeosPoolBuyOpenSeaClient.ts index a0b7b32..405af78 100644 --- a/src/Pool/NemeosPoolBuyOpenSeaClient.ts +++ b/src/Pool/NemeosPoolBuyOpenSeaClient.ts @@ -9,15 +9,22 @@ export class NemeosPoolBuyOpenSeaClient extends NemeosPoolClient { super(signer, enableLogging, nftCollectionAddress, nemeosPoolAddress, NemeosPoolMode.BuyOpenSea) } - public async previewLoan(nftId: number, loanDurationDays: number): Promise { + public async previewLoan(nftId: string, loanDurationDays: number): Promise { + const borrowerAddress = await this.signer.getAddress() + if (this.enableLogging) { console.log( `[nemeos][previewLoan_BuyOpenSea] Previewing loan for ` + - `nftCollectionAddress=${this.nftCollectionAddress}, nftId=${nftId}, loanDurationDays=${loanDurationDays}`, + `nftCollectionAddress=${this.nftCollectionAddress}, nftId=${nftId}, loanDurationDays=${loanDurationDays}, borrowerAddress=${borrowerAddress}`, ) } - const previewLoanData = await NemeosBackendClient.fetchLivePriceBuyOpenSeaData(this.nftCollectionAddress, nftId, loanDurationDays) + const previewLoanData = await NemeosBackendClient.fetchLivePriceBuyOpenSeaData( + this.nftCollectionAddress, + nftId, + loanDurationDays, + borrowerAddress, + ) if (this.enableLogging) { console.log('[nemeos][previewLoan_BuyOpenSea] Preview loan data:', previewLoanData) @@ -26,7 +33,7 @@ export class NemeosPoolBuyOpenSeaClient extends NemeosPoolClient { return previewLoanData } - public async startLoan(nftId: number, loanDurationDays: number): Promise { + public async startLoan(nftId: string, loanDurationDays: number): Promise { const borrowerAddress = await this.signer.getAddress() if (this.enableLogging) { @@ -37,10 +44,10 @@ export class NemeosPoolBuyOpenSeaClient extends NemeosPoolClient { } const startLoanData = await NemeosBackendClient.fetchStartLoanBuyOpenSeaData( - borrowerAddress, this.nftCollectionAddress, nftId, loanDurationDays, + borrowerAddress, ) const feeOverides = await getFeeOverrides(this.signer.provider!) diff --git a/src/Pool/NemeosPoolClient.ts b/src/Pool/NemeosPoolClient.ts index a992451..d6681a0 100644 --- a/src/Pool/NemeosPoolClient.ts +++ b/src/Pool/NemeosPoolClient.ts @@ -17,7 +17,7 @@ export abstract class NemeosPoolClient { this.poolContract = new ethers.Contract(nemeosPoolAddress, nemeosPoolInterface, signer) } - public async retrieveLoan(nftId: number): Promise { + public async retrieveLoan(nftId: string): Promise { const borrowerAddress = await this.signer.getAddress() if (this.enableLogging) { @@ -30,7 +30,7 @@ export abstract class NemeosPoolClient { return loan } - public async payNextLoanStep(nftId: number): Promise { + public async payNextLoanStep(nftId: string): Promise { const borrowerAddress = await this.signer.getAddress() if (this.enableLogging) { diff --git a/src/Pool/NemeosPoolDirectMintClient.ts b/src/Pool/NemeosPoolDirectMintClient.ts index 771d002..861ab9b 100644 --- a/src/Pool/NemeosPoolDirectMintClient.ts +++ b/src/Pool/NemeosPoolDirectMintClient.ts @@ -16,14 +16,20 @@ export class NemeosPoolDirectMintClient extends NemeosPoolClient { } public async previewLoan(loanDurationDays: number): Promise { + const borrowerAddress = await this.signer.getAddress() + if (this.enableLogging) { console.log( `[nemeos][previewLoan_DirectMint] Previewing loan for ` + - `nftCollectionAddress=${this.nftCollectionAddress}, loanDurationDays=${loanDurationDays}`, + `nftCollectionAddress=${this.nftCollectionAddress}, loanDurationDays=${loanDurationDays}, borrowerAddress=${borrowerAddress}`, ) } - const previewLoanData = await NemeosBackendClient.fetchLivePriceDirectMintData(this.nftCollectionAddress, loanDurationDays) + const previewLoanData = await NemeosBackendClient.fetchLivePriceDirectMintData( + this.nftCollectionAddress, + loanDurationDays, + borrowerAddress, + ) if (this.enableLogging) { console.log('[nemeos][previewLoan_DirectMint] Preview loan data:', previewLoanData) @@ -43,9 +49,9 @@ export class NemeosPoolDirectMintClient extends NemeosPoolClient { } const startLoanData = await NemeosBackendClient.fetchStartLoanDirectMintData( - borrowerAddress, this.nftCollectionAddress, loanDurationDays, + borrowerAddress, whitelistProof, ) const feeOverides = await getFeeOverrides(this.signer.provider!) diff --git a/tests/test.mjs b/tests/test.mjs index 14826d2..e42cc2e 100644 --- a/tests/test.mjs +++ b/tests/test.mjs @@ -21,7 +21,9 @@ async function main() { const provider = new ethers.JsonRpcProvider(process.env.INFURA_ENDPOINT_WITH_API_KEY) const wallet = new ethers.Wallet(process.env.WALLET_PRIVATE_KEY, provider) - const nemeosSdk = new NemeosSDK(wallet) + const nemeosSdk = new NemeosSDK(wallet, { + nemeosBackendEnvironment: NemeosSDK.NemeosBackendEnvironment.Development, + }) // const nemeosSdk = new NemeosSDK(wallet, { enableLogging: true }) // @@ -49,7 +51,7 @@ async function main() { const nemeosPoolBuyOpenSeaAddress = '0x812db15b8Bb43dBA89042eA8b919740C23aD48a3' const nftCollectionCyberKongzAddress = '0x15cd1cfCd48C06cfC44D433D66C7a9fE06b2C2c3' - const nftId1 = 231 + const nftId1 = '231' const loanDurationDays1 = 90 const nemeosPoolBuyOpenSeaClient = nemeosSdk.getNemeosPoolClient({ @@ -61,20 +63,24 @@ async function main() { const loan1 = await nemeosPoolBuyOpenSeaClient.previewLoan(nftId1, loanDurationDays1) console.dir(loan1, { depth: null }) await nemeosPoolBuyOpenSeaClient.startLoan(nftId1, loanDurationDays1) - // await new Promise(res => setTimeout(res, 10_000)) + await new Promise(res => setTimeout(res, 10_000)) + await nemeosPoolBuyOpenSeaClient.retrieveLoan(nftId1) await nemeosPoolBuyOpenSeaClient.payNextLoanStep(nftId1) + await new Promise(res => setTimeout(res, 3_000)) + await nemeosPoolBuyOpenSeaClient.retrieveLoan(nftId1) await nemeosPoolBuyOpenSeaClient.payNextLoanStep(nftId1) + await new Promise(res => setTimeout(res, 3_000)) + await nemeosPoolBuyOpenSeaClient.retrieveLoan(nftId1) // // NemeosPoolDirectMintClient // - const nemeosPoolDirectMintAddress = '0x0000000000000000000000000000000000000000' // FIXME: Update with the actual address - const nftCollectionWaldosAddress = '0x53ca73EE747ceD027c677feCCC13b885f31Ee4dF' - const nftId2 = 224 + const nemeosPoolDirectMintAddress = '0x4d09110F392C93D8f3e9843F0aBA40F6aB839C11' + const nftCollectionWaldosAddress = '0x0518EbdD8dE2cEAE8eaeD1c5cd93234bA14E75d0' const loanDurationDays2 = 61 const nemeosPoolDirectMintClient = nemeosSdk.getNemeosPoolClient({ @@ -83,16 +89,31 @@ async function main() { nemeosPoolMode: NemeosSDK.NemeosPoolMode.DirectMint, }) + console.log('Calling previewLoan...') const loan2 = await nemeosPoolDirectMintClient.previewLoan(loanDurationDays2) console.dir(loan2, { depth: null }) - await nemeosPoolDirectMintClient.isWhitelistedAddress(['0x0']) - await nemeosPoolDirectMintClient.startLoan(nftId2, ['0x0']) - // await new Promise(res => setTimeout(res, 10_000)) - await nemeosPoolDirectMintClient.retrieveLoan(nftId2) - await nemeosPoolDirectMintClient.payNextLoanStep(nftId2) - await nemeosPoolDirectMintClient.retrieveLoan(nftId2) - await nemeosPoolDirectMintClient.payNextLoanStep(nftId2) - await nemeosPoolDirectMintClient.retrieveLoan(nftId2) + // console.log('Calling isWhitelistedAddress...') + // await nemeosPoolDirectMintClient.isWhitelistedAddress(['0x0']) + console.log('Calling startLoan...') + await nemeosPoolDirectMintClient.startLoan(loanDurationDays2) + await new Promise(res => setTimeout(res, 10_000)) + + console.log('Calling retrieveLoan 1...') + await nemeosPoolDirectMintClient.retrieveLoan(loan2.nftFullLivePriceData.nextMintNftId) + console.log('Calling payNextLoanStep 1...') + await nemeosPoolDirectMintClient.payNextLoanStep(loan2.nftFullLivePriceData.nextMintNftId) + await new Promise(res => setTimeout(res, 3_000)) + + console.log('Calling retrieveLoan 2...') + await nemeosPoolDirectMintClient.retrieveLoan(loan2.nftFullLivePriceData.nextMintNftId) + console.log('Calling payNextLoanStep 2...') + await nemeosPoolDirectMintClient.payNextLoanStep(loan2.nftFullLivePriceData.nextMintNftId) + await new Promise(res => setTimeout(res, 3_000)) + + console.log('Calling retrieveLoan 3...') + await nemeosPoolDirectMintClient.retrieveLoan(loan2.nftFullLivePriceData.nextMintNftId) + console.log('Calling payNextLoanStep 3...') + await nemeosPoolDirectMintClient.payNextLoanStep(loan2.nftFullLivePriceData.nextMintNftId) } main().catch(console.error)