forked from goat-sdk/goat
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* save * package * tweak * lint
- Loading branch information
Showing
12 changed files
with
277 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "@goat-sdk/plugin-tensor", | ||
"version": "0.0.1", | ||
"files": ["dist/**/*", "README.md", "package.json"], | ||
"scripts": { | ||
"build": "tsup", | ||
"clean": "rm -rf dist", | ||
"test": "vitest run --passWithNoTests" | ||
}, | ||
"sideEffects": false, | ||
"main": "./dist/index.js", | ||
"module": "./dist/index.mjs", | ||
"types": "./dist/index.d.ts", | ||
"dependencies": { | ||
"@goat-sdk/core": "workspace:*", | ||
"@solana/web3.js": "catalog:", | ||
"zod": "catalog:" | ||
}, | ||
"peerDependencies": { | ||
"@goat-sdk/core": "workspace:*" | ||
}, | ||
"homepage": "https://ohmygoat.dev", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/goat-sdk/goat.git" | ||
}, | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/goat-sdk/goat/issues" | ||
}, | ||
"keywords": ["ai", "agents", "web3"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./plugin"; |
49 changes: 49 additions & 0 deletions
49
typescript/packages/plugins/tensor/src/methods/getBuyListingTransaction.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import type { SolanaWalletClient } from "@goat-sdk/core"; | ||
import type { Connection } from "@solana/web3.js"; | ||
import type { z } from "zod"; | ||
import type { getBuyListingTransactionResponseSchema } from "../parameters"; | ||
import { deserializeTxResponseToInstructions } from "../utils/deserializeTxResponseToInstructions"; | ||
import { getNftInfo } from "./getNftInfo"; | ||
|
||
export async function getBuyListingTransaction({ | ||
walletClient, | ||
mintHash, | ||
apiKey, | ||
connection, | ||
}: { walletClient: SolanaWalletClient; mintHash: string; apiKey: string; connection: Connection }) { | ||
const nftInfo = await getNftInfo({ mintHash, apiKey }); | ||
|
||
const price = nftInfo.listing?.price; | ||
const owner = nftInfo.owner; | ||
|
||
if (!price || !owner) { | ||
throw new Error(`No listing found for ${mintHash}`); | ||
} | ||
|
||
const queryParams = new URLSearchParams({ | ||
buyer: walletClient.getAddress(), | ||
mint: mintHash, | ||
owner, | ||
maxPrice: price, | ||
blockhash: "11111111111111111111111111111111", | ||
}); | ||
|
||
let data: z.infer<typeof getBuyListingTransactionResponseSchema>; | ||
try { | ||
const response = await fetch(`https://api.mainnet.tensordev.io/api/v1/tx/buy?${queryParams.toString()}`, { | ||
headers: { | ||
"Content-Type": "application/json", | ||
"x-tensor-api-key": apiKey, | ||
}, | ||
}); | ||
|
||
data = (await response.json()) as z.infer<typeof getBuyListingTransactionResponseSchema>; | ||
console.log(data); | ||
} catch (error) { | ||
throw new Error(`Failed to get buy listing transaction: ${error}`); | ||
} | ||
|
||
const { versionedTransaction, instructions } = await deserializeTxResponseToInstructions(connection, data); | ||
const lookupTableAddresses = versionedTransaction.message.addressTableLookups.map((lookup) => lookup.accountKey); | ||
return { versionedTransaction, instructions, lookupTableAddresses }; | ||
} |
20 changes: 20 additions & 0 deletions
20
typescript/packages/plugins/tensor/src/methods/getNftInfo.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import type { z } from "zod"; | ||
import type { getNftInfoResponseSchema } from "../parameters"; | ||
|
||
export async function getNftInfo({ mintHash, apiKey }: { mintHash: string; apiKey: string }) { | ||
let nftInfo: z.infer<typeof getNftInfoResponseSchema>; | ||
try { | ||
const response = await fetch(`https://api.mainnet.tensordev.io/api/v1/mint?mints=${mintHash}`, { | ||
headers: { | ||
"Content-Type": "application/json", | ||
"x-tensor-api-key": apiKey, | ||
}, | ||
}); | ||
|
||
nftInfo = (await response.json()) as z.infer<typeof getNftInfoResponseSchema>; | ||
} catch (error) { | ||
throw new Error(`Failed to get NFT info: ${error}`); | ||
} | ||
|
||
return nftInfo[0]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { z } from "zod"; | ||
|
||
export const getNftInfoParametersSchema = z.object({ | ||
mintHash: z.string(), | ||
}); | ||
|
||
export const getNftInfoResponseSchema = z.array( | ||
z.object({ | ||
onchainId: z.string(), | ||
attributes: z.array(z.any()), | ||
imageUri: z.string().optional(), | ||
lastSale: z | ||
.object({ | ||
price: z.string(), | ||
priceUnit: z.string(), | ||
}) | ||
.optional(), | ||
metadataUri: z.string().optional(), | ||
name: z.string().optional(), | ||
rarityRankTT: z.number().optional(), | ||
rarityRankTTStat: z.number().optional(), | ||
rarityRankHrtt: z.number().optional(), | ||
rarityRankStat: z.number().optional(), | ||
sellRoyaltyFeeBPS: z.number().optional(), | ||
tokenEdition: z.string().optional(), | ||
tokenStandard: z.string().optional(), | ||
hidden: z.boolean().optional(), | ||
compressed: z.boolean().optional(), | ||
verifiedCollection: z.string().optional(), | ||
owner: z.string().optional(), | ||
inscription: z.string().optional(), | ||
tokenProgram: z.string().optional(), | ||
metadataProgram: z.string().optional(), | ||
transferHookProgram: z.string().optional(), | ||
listingNormalizedPrice: z.string().optional(), | ||
hybridAmount: z.string().optional(), | ||
listing: z | ||
.object({ | ||
price: z.string(), | ||
txId: z.string(), | ||
seller: z.string(), | ||
source: z.string(), | ||
}) | ||
.optional(), | ||
slugDisplay: z.string().optional(), | ||
collId: z.string().optional(), | ||
collName: z.string().optional(), | ||
numMints: z.number().optional(), | ||
}), | ||
); | ||
|
||
export const getBuyListingTransactionResponseSchema = z.object({ | ||
txs: z.array( | ||
z.object({ | ||
tx: z.object({ | ||
type: z.string(), | ||
data: z.array(z.number()), | ||
}), | ||
txV0: z.object({ | ||
type: z.string(), | ||
data: z.array(z.number()), | ||
}), | ||
}), | ||
), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type { Plugin, SolanaWalletClient } from "@goat-sdk/core"; | ||
import type { Connection } from "@solana/web3.js"; | ||
import { getTools } from "./tools"; | ||
|
||
export function tensor(params: { connection: Connection; apiKey: string }): Plugin<SolanaWalletClient> { | ||
return { | ||
name: "tensor", | ||
supportsSmartWallets: () => false, | ||
supportsChain: (chain) => chain.type === "solana", | ||
getTools: async () => getTools(params), | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import type { SolanaWalletClient } from "@goat-sdk/core"; | ||
|
||
import type { DeferredTool } from "@goat-sdk/core"; | ||
import type { Connection } from "@solana/web3.js"; | ||
import { getBuyListingTransaction } from "./methods/getBuyListingTransaction"; | ||
import { getNftInfo } from "./methods/getNftInfo"; | ||
import { getNftInfoParametersSchema } from "./parameters"; | ||
|
||
export function getTools({ | ||
apiKey, | ||
connection, | ||
}: { apiKey: string; connection: Connection }): DeferredTool<SolanaWalletClient>[] { | ||
const getNftInfoTool: DeferredTool<SolanaWalletClient> = { | ||
name: "get_nft_info", | ||
description: "Gets information about a Solana NFT, from the Tensor API", | ||
parameters: getNftInfoParametersSchema, | ||
method: async (walletClient, parameters) => getNftInfo({ mintHash: parameters.mintHash, apiKey }), | ||
}; | ||
|
||
const buyListingTool: DeferredTool<SolanaWalletClient> = { | ||
name: "get_buy_listing_transaction", | ||
description: "Gets a transaction to buy an NFT from a listing from the Tensor API", | ||
parameters: getNftInfoParametersSchema, | ||
method: async (walletClient, parameters) => | ||
getBuyListingTransaction({ walletClient, mintHash: parameters.mintHash, apiKey, connection }), | ||
}; | ||
|
||
return [getNftInfoTool, buyListingTool]; | ||
} |
20 changes: 20 additions & 0 deletions
20
typescript/packages/plugins/tensor/src/utils/decompileVersionedTransactionToInstructions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { type DecompileArgs, TransactionMessage } from "@solana/web3.js"; | ||
|
||
import type { Connection, VersionedTransaction } from "@solana/web3.js"; | ||
|
||
export async function decompileVersionedTransactionToInstructions( | ||
connection: Connection, | ||
versionedTransaction: VersionedTransaction, | ||
) { | ||
const lookupTableAddresses = versionedTransaction.message.addressTableLookups.map((lookup) => lookup.accountKey); | ||
const addressLookupTableAccounts = await Promise.all( | ||
lookupTableAddresses.map((address) => | ||
connection.getAddressLookupTable(address).then((lookupTable) => lookupTable.value), | ||
), | ||
); | ||
const nonNullAddressLookupTableAccounts = addressLookupTableAccounts.filter((lookupTable) => lookupTable != null); | ||
const decompileArgs: DecompileArgs = { | ||
addressLookupTableAccounts: nonNullAddressLookupTableAccounts, | ||
}; | ||
return TransactionMessage.decompile(versionedTransaction.message, decompileArgs).instructions; | ||
} |
21 changes: 21 additions & 0 deletions
21
typescript/packages/plugins/tensor/src/utils/deserializeTxResponseToInstructions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { type Connection, VersionedTransaction } from "@solana/web3.js"; | ||
import type { z } from "zod"; | ||
import type { getBuyListingTransactionResponseSchema } from "../parameters"; | ||
import { decompileVersionedTransactionToInstructions } from "./decompileVersionedTransactionToInstructions"; | ||
|
||
export async function deserializeTxResponseToInstructions( | ||
connection: Connection, | ||
txResponse: z.infer<typeof getBuyListingTransactionResponseSchema>, | ||
) { | ||
const firstTransaction = txResponse.txs[0]; | ||
if (firstTransaction == null) { | ||
throw new Error("No transaction in response"); | ||
} | ||
const txV0 = firstTransaction.txV0; | ||
if (txV0 == null) { | ||
throw new Error("No txV0 in response"); | ||
} | ||
const versionedTransaction = VersionedTransaction.deserialize(Buffer.from(txV0.data)); | ||
const instructions = await decompileVersionedTransactionToInstructions(connection, versionedTransaction); | ||
return { versionedTransaction, instructions }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/tsconfig", | ||
"extends": "../../../tsconfig.base.json", | ||
"include": ["src/**/*"], | ||
"exclude": ["node_modules", "dist"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { defineConfig } from "tsup"; | ||
import { treeShakableConfig } from "../../../tsup.config.base"; | ||
|
||
export default defineConfig({ | ||
...treeShakableConfig, | ||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.