Repository: milktoastlab/SolanaNFTBot Branch: main Commit: e77710555004 Files: 80 Total size: 333.3 KB Directory structure: gitextract_jl1rlllm/ ├── .editorconfig ├── .github/ │ └── workflows/ │ └── main.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── babel.config.js ├── docker-compose.yml ├── jest.config.ts ├── nodemon.json ├── package.json ├── src/ │ ├── cli/ │ │ └── get-confirmed-transaction.ts │ ├── config/ │ │ ├── config.test.ts │ │ ├── config.ts │ │ └── index.ts │ ├── lib/ │ │ ├── discord/ │ │ │ ├── __mocks__/ │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ └── notifyDiscordSale.ts │ │ ├── logger/ │ │ │ ├── index.ts │ │ │ └── logger.ts │ │ ├── marketplaces/ │ │ │ ├── __fixtures__/ │ │ │ │ ├── alphaArtSaleTx.ts │ │ │ │ ├── digitalEyesSaleTx.ts │ │ │ │ ├── exchangeArtSaleTx.ts │ │ │ │ ├── exchangeArtSaleTxV2.ts │ │ │ │ ├── magicEdenFailedTx.ts │ │ │ │ ├── magicEdenSaleFromBidTx.ts │ │ │ │ ├── magicEdenSaleTx.ts │ │ │ │ ├── magicEdenSaleTxV2.ts │ │ │ │ ├── openSeaBidTx.ts │ │ │ │ ├── openSeaSale2Tx.ts │ │ │ │ ├── openSeaSale3Tx.ts │ │ │ │ ├── openSeaSaleTx.ts │ │ │ │ ├── solanartBidTx.ts │ │ │ │ ├── solanartDelistingTx.ts │ │ │ │ ├── solanartListingTx.ts │ │ │ │ ├── solanartSaleFromBidTx.ts │ │ │ │ ├── solanartSaleTx.ts │ │ │ │ ├── solanartSalesTxWithFloatingLamport.ts │ │ │ │ └── solseaSaleTx.ts │ │ │ ├── alphaArt.test.ts │ │ │ ├── alphaArt.ts │ │ │ ├── digitalEyes.test.ts │ │ │ ├── digitalEyes.ts │ │ │ ├── exchangeArt.test.ts │ │ │ ├── exchangeArt.ts │ │ │ ├── helper.test.ts │ │ │ ├── helper.ts │ │ │ ├── index.ts │ │ │ ├── magicEden.test.ts │ │ │ ├── magicEden.ts │ │ │ ├── marketplaces.ts │ │ │ ├── openSea.test.ts │ │ │ ├── openSea.ts │ │ │ ├── parseNFTSaleForAllMarkets.test.ts │ │ │ ├── parseNFTSaleForAllMarkets.ts │ │ │ ├── solanart.test.ts │ │ │ ├── solanart.ts │ │ │ ├── solsea.test.ts │ │ │ ├── solsea.ts │ │ │ └── types.ts │ │ ├── notifier/ │ │ │ ├── index.ts │ │ │ ├── notifier.test.ts │ │ │ └── notifier.ts │ │ ├── sleep/ │ │ │ ├── index.ts │ │ │ └── sleep.ts │ │ ├── solana/ │ │ │ ├── NFTData.ts │ │ │ ├── connection.ts │ │ │ └── index.ts │ │ ├── truncateForAddress.ts │ │ └── twitter/ │ │ ├── index.ts │ │ └── notifyTwitter.ts │ ├── server.ts │ └── workers/ │ ├── initWorkers.test.ts │ ├── initWorkers.ts │ ├── notifyMagicEdenNFTSalesWorker.test.ts │ ├── notifyMagicEdenNFTSalesWorker.ts │ ├── notifyNFTSalesWorker.test.ts │ ├── notifyNFTSalesWorker.ts │ └── types.ts └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ # top-most EditorConfig file root = true # Unix-style newlines with a newline ending every file [*] insert_final_newline = true # 2 space indentation [*.{ts,tsx}] indent_style = space indent_size = 2 # Matches the exact files either package.json or .travis.yml [{package.json,.travis.yml}] indent_style = space indent_size = 2 ================================================ FILE: .github/workflows/main.yml ================================================ # This is a basic workflow to help you get started with Actions name: CI # Controls when the workflow will run on: # Triggers the workflow on push or pull request events but only for the main branch push: branches: [ main ] pull_request: branches: [ main ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" build: # The type of runner that the job will run on runs-on: ubuntu-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 - name: Setup Yarn # You may pin to the exact commit or the version. # uses: mskelton/setup-yarn@9a4157decaf2f0a260628079af3512df41f7823d uses: mskelton/setup-yarn@v1.0.1 with: # Additional flags to pass to the install command. flags: --frozen-lockfile # Node version to use, defaults to the current LTS version. node-version: 16.x - name: Build run: yarn build - name: Test run: yarn test - name: Lint run: yarn lint-format ================================================ FILE: .gitignore ================================================ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies node_modules /.pnp .pnp.js # yarn .yarn # testing /coverage # next.js /.next/ /out/ # production /build # misc .DS_Store *.pem # debug npm-debug.log* yarn-debug.log* yarn-error.log* # local env files .env.local .env.development.local .env.test.local .env.production.local # vercel .vercel .idea dist ================================================ FILE: Dockerfile ================================================ FROM node:16 as dependencies WORKDIR /solananftbot COPY package.json yarn.lock .env ./ RUN yarn install --frozen-lockfile FROM node:16 as builder WORKDIR /solananftbot COPY . . COPY --from=dependencies /solananftbot/node_modules ./node_modules COPY --from=dependencies /solananftbot/.env ./.env RUN yarn build FROM node:16 as runner WORKDIR /solananftbot ENV NODE_ENV production # If you are using a custom next.config.js file, uncomment this line. # COPY --from=builder /solananftbot/next.config.js ./ COPY --from=builder /solananftbot/dist ./dist COPY --from=builder /solananftbot/node_modules ./node_modules COPY --from=builder /solananftbot/package.json ./package.json COPY --from=builder /solananftbot/.env ./.env EXPOSE 4000 CMD ["yarn", "start"] ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2021 milktoastlab Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Solana NFT Bot Solana NFT bot is a helpful bot for your Solana NFT projects. ## Sponsor This project is proudly sponsored by [milktoast.world](https://milktoast.world): An NFT project that aims to spread happiness and cheer. If you find this project useful, please support us by following [Milktoast](https://twitter.com/milktoastnft) and [KryptoJ](https://twitter.com/kryptoj_) on Twitter! ## Features - [x] Notify discord channel on each purchase in marketplaces. - [x] Send Twitter tweet on each purchase in marketplaces. (Experimental) - [x] [Support major marketplaces](#marketplace-support) Screen Shot 2022-01-30 at 10 34 53 pm ## Running using docker ### Requirement * [Docker](https://www.docker.com/products/docker-desktop) >= v20.10 * If you're new to Docker, we recommend going through their [get started page](https://docs.docker.com/get-started/) to gain a basic understanding of Docker before moving forward. * A Solana RPC node/server - This is needed so the bot know where to call to fetch solana transactions. Here are some potential routes to get a node: * https://quicknode.com/ * [Run your own](https://medium.com/@MisterKevin_js/how-to-run-your-own-solana-rpc-endpoint-on-figments-datahub-e9ca881bebb7) ### Instructions #### Run bot locally using docker in the terminal If you're new to docker, before starting I recommend Run the following command with your own secrets replaced with your own configuration: ``` docker run --name nftbot -d -p 4000:4000 -e SOLANA_RPC=YOURRPCURL -e DISCORD_BOT_TOKEN=YOURDISCORDTOKEN -e SUBSCRIPTION_DISCORD_CHANNEL_ID=YOURCHANNELID -e SUBSCRIPTION_MINT_ADDRESS=YOURMINTADDRESS milktoastlab/solananftbot ``` Note: The command above is tested in linux/unix env only. You may have a different experience in Windows. Please check the [documentation on how to run docker command in windows](https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/run-your-first-container) if you need any help. View logs ``` docker logs ntfbot ``` To make sure the bot is working properly, use [/test-sale-tx](src/server.ts#L47) endpoint ``` curl "http://localhost:4000/test-sale-tx?signature={sale_transaction_signature}&channelId={discord_channel_id}" ``` In case of *DiscordAPIError: Missing Access* error, check if the bot has been invited to the channel. Go to the channel, click "Add members or roles" and add your bot account as a member. Alternatively, you can run it using docker-compose: Update `.env` with your secret and run ``` docker-compose up -d bot ``` See [here](#configurable-environments) for more details on environment variables View logs ``` docker-compose logs bot ``` ## Running in development ### Requirement * Node >= 16.6 * Yarn ### Instructions #### 1. Install dependencies ``` yarn install ``` #### 2. Update .env with your secrets Follow the instructions [here](#configurable-environments) #### 3. Run the server ``` yarn dev ``` ## Configurable environments Here are a list of environments you need to configure before running the NFT bot. ```sh # RPC node url SOLANA_RPC= # Discord bot secret DISCORD_BOT_TOKEN= # The discord channel to notify SUBSCRIPTION_DISCORD_CHANNEL_ID= # Mint address to watch for sales SUBSCRIPTION_MINT_ADDRESS= # Twitter secrets TWITTER_API_KEY= TWITTER_API_KEY_SECRET= TWITTER_ACCESS_TOKEN= TWITTER_ACCESS_TOKEN_SECRET= # Magic eden API MAGIC_EDEN_URL=https://api-mainnet.magiceden.dev/v2 # Enter the NFT collection that you want to track MAGIC_EDEN_COLLECTION= # The discord channel to notify MAGIC_EDEN_DISCORD_CHANNEL_ID= ``` https://github.com/milktoastlab/SolanaNFTBot/blob/main/.env ### Variable breakdowns #### DISCORD_BOT_TOKEN This is your discord bot secret. If you don't have a discord bot yet, you can create one following the instructions here: https://discordpy.readthedocs.io/en/stable/discord.html Make sure your bot has the required permissions: * View channels * Read/Send messages * Send messages * Embed links Screen Shot 2021-10-31 at 9 25 31 am #### SUBSCRIPTION_DISCORD_CHANNEL_ID This is the ID of the discord channel you want to send notifications to. You will need to enable developer mode have access the channel IDs. Here are the instructions: https://support.discord.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID- #### SUBSCRIPTION_MINT_ADDRESS This is the address that you want the Solana NFT bot to watch for notifications. It needs to be one of the creator addresses: Screen Shot 2021-11-12 at 6 16 31 pm _Note: Avoid personal addresses because it could detect unwanted sales._ ##### Watch multiple addresses You can watch multiple addresses at once by using a comma between addresses: ```bash SUBSCRIPTION_MINT_ADDRESS=add123,add1235 ``` This feature reduces the need to run multiple containers in production. #### Twitter variables __Experimental:__ We haven't stress test Twitter notification on high volume projects. We recommend you have a good internet connection for your bot if you want to use this feature, because for each notification, the bot will upload the nft image to Twitter for display. Create a Github issue to let us know if you encounter any problems. To post sales notification tweets to Twitter via the API, you will first need Elevated access to the Twitter API. While logged in to the account you want to use the Twitter API for, apply for Elevated access to the twitter API by clicking the link here and following the steps: https://developer.twitter.com/en/portal/petition/essential/basic-info The approval process may take a while. Create a new project, and create a new App under that project. The API Key and secret will be displayed to you there, which you'll assign to `TWITTER_API_KEY` and `TWITTER_API_KEY_SECRET` respectively. Then, click on the Keys and tokens tab, and generate the Access Token and Secret. Assign these to `TWITTER_ACCESS_TOKEN` and `TWITTER_ACCESS_TOKEN_SECRET` respectively. ### Magic Eden variables Magic eden's NFT trading program has changed to V2, which means the old way of detecting sales won't work anymore. We have updated the bot to use the new API to detect sales. To enable this feature, you will need to add the following variables to your `.env` file: __MAGIC_EDEN_COLLECTION__ This is the collection key to magic eden. To find our what it is, navigate to the collection page and look at the url. It should be the last part of the url. ``` Example: https://magiceden.io/marketplace/milktoast ``` The collection key is "milktoast" __MAGIC_EDEN_DISCORD_CHANNEL_ID__ This is the discord channel to notify. Same as `SUBSCRIPTION_DISCORD_CHANNEL_ID` but it doesn't support multiple channels at the moment. ## Production deployment The solana nft bot is containerized, you can deploy it on any hosting service that supports docker. Here are some options: * [Akash Network](https://akash.network), a decentralized cloud compute marketplace. [Click here for the step by step guide.](https://medium.com/@kryptoj/how-to-host-a-solana-nft-bot-on-the-akash-network-no-code-ccbeb9ce35d1) * https://www.ibm.com/cloud/code-engine * [Digital Ocean](https://www.digitalocean.com/products/droplets) ## Marketplace support - [x] [Magic Eden](https://magiceden.io/) - [x] [Solanart](http://solanart.io/) - [x] [Digital Eyes](https://digitaleyes.market/) - [x] [Alpha Art](https://alpha.art/) - [x] [Exchange Art](https://exchange.art/) - [x] [Solsea](https://solsea.io/) - [x] [OpenSea](https://opensea.io/) ### Adding new marketplace SolanaNFTBot aim to support as many marketplaces are possible. Here is the instruction on how you can add support to other marketplaces. #### 1. Add a new marketplace config Use `src/lib/marketplaces/solsea.ts` as example #### 2. Write a test for the marketplace Use `src/lib/marketplaces/solsea.test.ts` as example #### 3. Add the new marketplace to the existing list `src/lib/marketplaces/marketplaces.ts` ## Support If you have any questions or feedback, feel free to jump into our discord #dev-talk channel and have a chat. https://discord.com/invite/GYxur2tvzP ================================================ FILE: babel.config.js ================================================ module.exports = { presets: [ ["@babel/preset-env", { targets: { node: "current" } }], "@babel/preset-typescript", ], }; ================================================ FILE: docker-compose.yml ================================================ version: "3.9" services: bot: image: milktoastlab/solananftbot ports: - "4000:4000" env_file: - .env ================================================ FILE: jest.config.ts ================================================ /* * For a detailed explanation regarding each configuration property, visit: * https://jestjs.io/docs/configuration */ module.exports = { // All imported modules in your tests should be mocked automatically // automock: false, // Stop running tests after `n` failures // bail: 0, // The directory where Jest should store its cached dependency information // cacheDirectory: "/private/var/folders/w6/bzw5qrfd6_n14pqvd1khrx8r0000gn/T/jest_dx", // Automatically clear mock calls and instances between every test clearMocks: true, // Indicates whether the coverage information should be collected while executing the test collectCoverage: true, // An array of glob patterns indicating a set of files for which coverage information should be collected // collectCoverageFrom: undefined, // The directory where Jest should output its coverage files coverageDirectory: "coverage", // An array of regexp pattern strings used to skip coverage collection coveragePathIgnorePatterns: [ "/node_modules/", "/__fixtures__/", ], // Indicates which provider should be used to instrument code for coverage coverageProvider: "babel", // A list of reporter names that Jest uses when writing coverage reports // coverageReporters: [ // "json", // "text", // "lcov", // "clover" // ], // An object that configures minimum threshold enforcement for coverage results // coverageThreshold: undefined, // A path to a custom dependency extractor // dependencyExtractor: undefined, // Make calling deprecated APIs throw helpful error messages // errorOnDeprecated: false, // Force coverage collection from ignored files using an array of glob patterns // forceCoverageMatch: [], // A path to a module which exports an async function that is triggered once before all test suites // globalSetup: undefined, // A path to a module which exports an async function that is triggered once after all test suites // globalTeardown: undefined, // A set of global variables that need to be available in all test environments // globals: {}, // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. // maxWorkers: "50%", // An array of directory names to be searched recursively up from the requiring module's location moduleDirectories: [ "node_modules", "src" ], // An array of file extensions your modules use // moduleFileExtensions: [ // "js", // "jsx", // "ts", // "tsx", // "json", // "node" // ], // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module // moduleNameMapper: {}, // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader // modulePathIgnorePatterns: [], // Activates notifications for test results // notify: false, // An enum that specifies notification mode. Requires { notify: true } // notifyMode: "failure-change", // A preset that is used as a base for Jest's configuration // preset: undefined, // Run tests from one or more projects // projects: undefined, // Use this configuration option to add custom reporters to Jest // reporters: undefined, // Automatically reset mock state between every test // resetMocks: false, // Reset the module registry before running each individual test // resetModules: false, // A path to a custom resolver // resolver: undefined, // Automatically restore mock state between every test // restoreMocks: false, // The root directory that Jest should scan for tests and modules within // rootDir: './src', // A list of paths to directories that Jest should use to search for files in // roots: [ // "src" // ], // Allows you to use a custom runner instead of Jest's default test runner // runner: "jest-runner", // The paths to modules that run some code to configure or set up the testing environment before each test // setupFiles: [], // A list of paths to modules that run some code to configure or set up the testing framework before each test // setupFilesAfterEnv: [], // The number of seconds after which a test is considered as slow and reported as such in the results. // slowTestThreshold: 5, // A list of paths to snapshot serializer modules Jest should use for snapshot testing // snapshotSerializers: [], // The test environment that will be used for testing // testEnvironment: "jest-environment-node", // Options that will be passed to the testEnvironment // testEnvironmentOptions: {}, // Adds a location field to test results // testLocationInResults: false, // The glob patterns Jest uses to detect test files testMatch: ["**/*.test.ts"], // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped // testPathIgnorePatterns: [ // "/node_modules/" // ], // The regexp pattern or array of patterns that Jest uses to detect test files // testRegex: [], // This option allows the use of a custom results processor // testResultsProcessor: undefined, // This option allows use of a custom test runner // testRunner: "jest-circus/runner", // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href // testURL: "http://localhost", // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" // timers: "real", // A map from regular expressions to paths to transformers // transform: undefined, // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation // transformIgnorePatterns: [ // "/node_modules/", // "\\.pnp\\.[^\\/]+$" // ], // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them // unmockedModulePathPatterns: undefined, // Indicates whether each individual test should be reported during the run // verbose: undefined, // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode // watchPathIgnorePatterns: [], // Whether to use watchman for file crawling // watchman: true, }; ================================================ FILE: nodemon.json ================================================ { "ignore": ["**/*.test.ts", "node_modules"], "watch": ["src"], "exec": "yarn ts-run", "ext": "ts" } ================================================ FILE: package.json ================================================ { "name": "@milktoast-lab/SolNFTBot", "version": "0.15.2", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", "license": "MIT", "engines": { "node": ">=16.6" }, "scripts": { "dev": "nodemon", "ts-run": "ts-node src/server.ts", "build": "tsc", "start": "NODE_PATH=./dist/src NODE_ENV=production node dist/src/server.js", "test": "jest --no-watchman", "lint-format": "prettier -c ./src/**/*.ts", "fix-format": "prettier -w ./src/**/*.ts", "transaction": "ts-node --project tsconfig.json -r dotenv/config ./src/cli/get-confirmed-transaction.ts" }, "dependencies": { "@discordjs/builders": "^0.8.1", "@metaplex-foundation/js": "^0.17.0", "@solana/web3.js": "^1.64.0", "axios": "^0.25.0", "discord.js": "^13.2.0", "dotenv": "^16.0.3", "express": "^4.17.1", "file-type": "16.5.4", "queue": "^6.0.2", "ts-node": "^10.4.0", "twitter-api-v2": "^1.9.0" }, "devDependencies": { "@babel/core": "^7.15.8", "@babel/preset-env": "^7.15.8", "@babel/preset-typescript": "^7.15.0", "@types/express": "^4.17.13", "@types/jest": "^27.0.2", "@types/node": "^16.11.4", "babel-jest": "^27.3.1", "jest": "^27.2.5", "nodemon": "^2.0.14", "prettier": "^2.4.1", "tsconfig-paths": "^3.11.0", "typescript": "4.4.4" } } ================================================ FILE: src/cli/get-confirmed-transaction.ts ================================================ import { newConnection } from "../lib/solana"; async function run(signature: string) { const conn = newConnection(); const tx = await conn.getParsedConfirmedTransaction(signature); if (!tx) { console.log(`No transaction found for ${signature}`); return; } console.log(JSON.stringify(tx)); } run(process.env.TX as string); ================================================ FILE: src/config/config.test.ts ================================================ import { loadConfig } from "./config"; jest.spyOn(console, "error"); describe("config", () => { test("load single subscription", () => { const config = loadConfig({ SUBSCRIPTION_MINT_ADDRESS: "add123", SUBSCRIPTION_DISCORD_CHANNEL_ID: "discord123", }); expect(config.subscriptions.length).toEqual(1); const { type, discordChannelId, mintAddress } = config.subscriptions[0]; expect(type).toEqual("NFTSale"); expect(mintAddress).toEqual("add123"); expect(discordChannelId).toEqual("discord123"); }); test("load multiple subscriptions", () => { const config = loadConfig({ SUBSCRIPTION_MINT_ADDRESS: "add123,add456", SUBSCRIPTION_DISCORD_CHANNEL_ID: "discord123,discord456", }); expect(config.subscriptions.length).toEqual(2); const subscription0 = config.subscriptions[0]; expect(subscription0.type).toEqual("NFTSale"); expect(subscription0.mintAddress).toEqual("add123"); expect(subscription0.discordChannelId).toEqual("discord123"); const subscription1 = config.subscriptions[1]; expect(subscription1.type).toEqual("NFTSale"); expect(subscription1.mintAddress).toEqual("add456"); expect(subscription1.discordChannelId).toEqual("discord456"); }); test("load multiple subscriptions with one address", () => { const config = loadConfig({ SUBSCRIPTION_MINT_ADDRESS: "add123,add456", SUBSCRIPTION_DISCORD_CHANNEL_ID: "discord123", }); expect(config.subscriptions.length).toEqual(2); const subscription0 = config.subscriptions[0]; expect(subscription0.type).toEqual("NFTSale"); expect(subscription0.mintAddress).toEqual("add123"); expect(subscription0.discordChannelId).toEqual("discord123"); const subscription1 = config.subscriptions[1]; expect(subscription1.type).toEqual("NFTSale"); expect(subscription1.mintAddress).toEqual("add456"); expect(subscription1.discordChannelId).toEqual("discord123"); }); test("do not load invalid subscription", () => { const config = loadConfig({ SUBSCRIPTION_MINT_ADDRESS: "", SUBSCRIPTION_DISCORD_CHANNEL_ID: "discord123", }); expect(config.subscriptions.length).toEqual(0); }); }); ================================================ FILE: src/config/config.ts ================================================ import logger from "lib/logger"; export interface Subscription { discordChannelId: string; type: "NFTSale"; mintAddress: string; } interface TwitterConfig { appKey: string; appSecret: string; accessToken: string; accessSecret: string; } export interface MagicEdenConfig { url: string; collection: string; discordChannelId: string; } export interface Config { twitter: TwitterConfig; discordBotToken: string; queueConcurrency: number; subscriptions: Subscription[]; magicEdenConfig: MagicEdenConfig; } export type Env = { [key: string]: string }; export interface MutableConfig extends Config { setSubscriptions(subscriptions: Subscription[]): Promise; addSubscription(subscription: Subscription): Promise; } function loadSubscriptions(env: Env): Subscription[] { if (!env.SUBSCRIPTION_MINT_ADDRESS || !env.SUBSCRIPTION_DISCORD_CHANNEL_ID) { return []; } const addresses = env.SUBSCRIPTION_MINT_ADDRESS.split(","); const discordChannels = env.SUBSCRIPTION_DISCORD_CHANNEL_ID.split(","); if ( discordChannels.length != addresses.length && discordChannels.length !== 1 ) { logger.error( `Invalid number of discord channel ids: ${discordChannels.length}` ); return []; } const subscriptions: Subscription[] = []; addresses.forEach((address, idx) => { if (!address) { return; } const channel = discordChannels[idx] || discordChannels[0]; if (!channel) { return; } subscriptions.push({ type: "NFTSale", discordChannelId: channel, mintAddress: address, }); }); return subscriptions; } export function loadConfig(env: Env): MutableConfig { const config: Config = { twitter: { appKey: env.TWITTER_API_KEY || "", appSecret: env.TWITTER_API_KEY_SECRET || "", accessToken: env.TWITTER_ACCESS_TOKEN || "", accessSecret: env.TWITTER_ACCESS_TOKEN_SECRET || "", }, discordBotToken: env.DISCORD_BOT_TOKEN || "", queueConcurrency: parseInt(env.QUEUE_CONCURRENCY || "2", 10), subscriptions: loadSubscriptions(env), magicEdenConfig: { url: env.MAGIC_EDEN_URL || "", collection: env.MAGIC_EDEN_COLLECTION || "", discordChannelId: env.MAGIC_EDEN_DISCORD_CHANNEL_ID || "", }, }; return { ...config, async setSubscriptions(subscriptions: Subscription[]): Promise { this.subscriptions = subscriptions; }, async addSubscription(subscription: Subscription): Promise { this.subscriptions.push(subscription); }, }; } ================================================ FILE: src/config/index.ts ================================================ export * from "./config"; ================================================ FILE: src/lib/discord/__mocks__/index.ts ================================================ import Discord, {TextChannel} from "discord.js"; export async function initClient(): Promise { const discordClient = new Discord.Client({ intents: [] }); jest.spyOn(discordClient, "isReady").mockImplementation(() => true); jest.spyOn(discordClient.channels, "fetch").mockImplementation(async () => { return { send() {} } as unknown as TextChannel; }); return discordClient; }; export async function fetchDiscordChannel( client: Discord.Client, channelId: string ): Promise { return {} as TextChannel; } ================================================ FILE: src/lib/discord/index.ts ================================================ import Discord, { Intents, TextChannel } from "discord.js"; import logger from "lib/logger"; const myIntents = new Intents(); myIntents.add(Intents.FLAGS.DIRECT_MESSAGES, Intents.FLAGS.GUILD_MESSAGES); let client: Discord.Client; export async function initClient( token: string ): Promise { if (!client) { client = new Discord.Client({ intents: myIntents, }); } if (client.isReady()) { return client; } return new Promise((resolve) => { client.on("ready", () => { logger.log(`Logged in as ${client.user?.tag}!`); resolve(client); }); client.login(token); }); } export async function fetchDiscordChannel( client: Discord.Client, channelId: string ): Promise { if (!client.isReady()) { return; } const channel = (await client.channels.fetch(channelId)) as TextChannel; if (!channel) { logger.warn("Can't see channel"); return; } if (!channel.send) { logger.warn("Channel must be a TextChannel"); return; } return channel; } ================================================ FILE: src/lib/discord/notifyDiscordSale.ts ================================================ import Discord, { MessageActionRow, MessageEmbed, TextChannel, } from "discord.js"; import { Marketplace, NFTSale, SaleMethod } from "lib/marketplaces"; import truncateForAddress from "lib/truncateForAddress"; import logger from "lib/logger"; import { fetchDiscordChannel } from "./index"; const status: { totalNotified: number; lastNotified?: Date; } = { totalNotified: 0, }; export function getStatus() { return status; } export default async function notifyDiscordSale( client: Discord.Client, channelId: string, nftSale: NFTSale, test?: boolean ) { const channel = await fetchDiscordChannel(client, channelId); if (!channel) { return; } const { marketplace, nftData } = nftSale; if (!nftData) { logger.log("missing nft Data for token: ", nftSale.token); return; } const method = `Sold${ nftSale.method === SaleMethod.Bid ? " via bidding" : "" }`; const description = `${method} for ${nftSale.getPriceInSOL()} S◎L on ${ marketplace.name }`; const actionRowMsg = new MessageActionRow({ type: 1, components: [ { style: 5, label: `View Transaction`, url: `https://solscan.io/tx/${nftSale.transaction}`, disabled: false, type: 2, }, { style: 5, label: `View Token`, url: `https://solscan.io/token/${nftSale.token}`, disabled: false, type: 2, }, ], }); const embedMsg = new MessageEmbed({ color: 0x0099ff, title: nftData.name, url: marketplace.itemURL(nftSale.token), timestamp: `${nftSale.soldAt}`, fields: [ { name: "Price", value: `${nftSale.getPriceInSOL().toFixed(2)} S◎L ${ nftSale.method === SaleMethod.Bid ? "(Via bidding)" : "" }`, inline: false, }, { name: "Buyer", value: formatAddress(marketplace, nftSale.buyer), inline: true, }, { name: "Seller", value: nftSale.seller ? formatAddress(marketplace, nftSale.seller) : "unknown", inline: true, }, ], image: { url: encodeURI(nftData.image), width: 600, height: 600, }, footer: { text: `Sold on ${marketplace.name}`, icon_url: marketplace.iconURL, proxy_icon_url: marketplace.itemURL(nftSale.token), }, }); await channel.send({ components: [actionRowMsg], embeds: [embedMsg], }); const logMsg = `Notified discord #${channel.name}: ${nftData.name} - ${description}`; logger.log(logMsg); if (!test) { status.lastNotified = new Date(); status.totalNotified++; } } function formatAddress(marketplace: Marketplace, address: string): string { if (!address) { return ""; } return `[${truncateForAddress(address)}](${marketplace.profileURL(address)})`; } ================================================ FILE: src/lib/logger/index.ts ================================================ export { default } from "./logger"; ================================================ FILE: src/lib/logger/logger.ts ================================================ const logger = { prefix(level: string) { return `[${level}] ${new Date().toISOString()}:`; }, log(msg?: any, ...optionalParams: any[]) { console.log(this.prefix("info"), msg, ...optionalParams); }, warn(msg?: any, ...optionalParams: any[]) { console.warn(this.prefix("warning"), msg, ...optionalParams); }, error(msg?: any, ...optionalParams: any[]) { console.error(this.prefix("error"), msg, ...optionalParams); }, }; export default logger; ================================================ FILE: src/lib/marketplaces/__fixtures__/alphaArtSaleTx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1636257741, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "5x13F4NupczfwP9EjJP4wcDQWinhUk2wXNeS1xYMzAgR", lamports: 2039280, source: "CScUB4iBTfCWaFkj5gRpXx42HVpAgDvPJgbQxtETRXi1", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "5x13F4NupczfwP9EjJP4wcDQWinhUk2wXNeS1xYMzAgR", space: 165, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "5x13F4NupczfwP9EjJP4wcDQWinhUk2wXNeS1xYMzAgR", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "5x13F4NupczfwP9EjJP4wcDQWinhUk2wXNeS1xYMzAgR", mint: "14Cc7DA6MwpNdAZZYdLxK6WQ9meMaeLX1WsCyLRf5nqw", owner: "CScUB4iBTfCWaFkj5gRpXx42HVpAgDvPJgbQxtETRXi1", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, { index: 1, instructions: [ { parsed: { info: { destination: "D3wgcpWjAWR3GREbkyuGr3bNLHfdQsLr5hN2AvSP8pBi", lamports: 15600000, source: "CScUB4iBTfCWaFkj5gRpXx42HVpAgDvPJgbQxtETRXi1", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "67dNFe4z58pmTs1DshwTm2rT127XtBCeRaBxDUYwaLfu", lamports: 78000000, source: "CScUB4iBTfCWaFkj5gRpXx42HVpAgDvPJgbQxtETRXi1", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "Gi44PdWS951cZjR5hgW1VnvKkxcV3scyHFpAFY3QpYSb", lamports: 686400000, source: "CScUB4iBTfCWaFkj5gRpXx42HVpAgDvPJgbQxtETRXi1", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { amount: "1", destination: "5x13F4NupczfwP9EjJP4wcDQWinhUk2wXNeS1xYMzAgR", multisigAuthority: "4pUQS4Jo2dsfWzt3VgHXy3H6RYnEDd11oWPiaM2rdAPw", signers: ["4pUQS4Jo2dsfWzt3VgHXy3H6RYnEDd11oWPiaM2rdAPw"], source: "EDAWjyzq1Mf4JDue3tNiqhGeUg8az41EsHEQcEmjnZBY", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { account: "EDAWjyzq1Mf4JDue3tNiqhGeUg8az41EsHEQcEmjnZBY", destination: "Gi44PdWS951cZjR5hgW1VnvKkxcV3scyHFpAFY3QpYSb", multisigOwner: "4pUQS4Jo2dsfWzt3VgHXy3H6RYnEDd11oWPiaM2rdAPw", signers: ["4pUQS4Jo2dsfWzt3VgHXy3H6RYnEDd11oWPiaM2rdAPw"], }, type: "closeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]", "Program log: Transfer 2039280 lamports to the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the associated token account to the SPL Token program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Initialize the associated token account", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3449 of 179574 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 24524 of 200000 compute units", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success", "Program HZaWndaNWHFDd9Dhk5pqUUtsmoBCqzb1MLu3NAh1VX6B invoke [1]", "Program log: Instruction: Exchange", "Program log: Transfer 15600000 service fee to fee_collector", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Send 78000000 lamports royalty to 67dNFe4z58pmTs1DshwTm2rT127XtBCeRaBxDUYwaLfu", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Send Remaining 686400000 lamports to initializer", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Calling the token program to transfer tokens to the taker...", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3246 of 157040 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: CloseAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2422 of 150764 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program log: Closing the escrow account...", "Program HZaWndaNWHFDd9Dhk5pqUUtsmoBCqzb1MLu3NAh1VX6B consumed 53096 of 200000 compute units", "Program HZaWndaNWHFDd9Dhk5pqUUtsmoBCqzb1MLu3NAh1VX6B success", ], postBalances: [ 445990595, 2039280, 0, 2334481480, 0, 430340495378, 4572720, 142232472680, 1461600, 1, 1089991680, 1009200, 0, 5616720, 9221625333, 898174080, 1141440, ], postTokenBalances: [ { accountIndex: 1, mint: "14Cc7DA6MwpNdAZZYdLxK6WQ9meMaeLX1WsCyLRf5nqw", owner: "CScUB4iBTfCWaFkj5gRpXx42HVpAgDvPJgbQxtETRXi1", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], preBalances: [ 1228034875, 0, 2039280, 1644357880, 1684320, 430324895378, 4572720, 142154472680, 1461600, 1, 1089991680, 1009200, 0, 5616720, 9221625333, 898174080, 1141440, ], preTokenBalances: [ { accountIndex: 2, mint: "14Cc7DA6MwpNdAZZYdLxK6WQ9meMaeLX1WsCyLRf5nqw", owner: "4pUQS4Jo2dsfWzt3VgHXy3H6RYnEDd11oWPiaM2rdAPw", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 105618616, transaction: { message: { accountKeys: [ { pubkey: "CScUB4iBTfCWaFkj5gRpXx42HVpAgDvPJgbQxtETRXi1", signer: true, writable: true, }, { pubkey: "5x13F4NupczfwP9EjJP4wcDQWinhUk2wXNeS1xYMzAgR", signer: false, writable: true, }, { pubkey: "EDAWjyzq1Mf4JDue3tNiqhGeUg8az41EsHEQcEmjnZBY", signer: false, writable: true, }, { pubkey: "Gi44PdWS951cZjR5hgW1VnvKkxcV3scyHFpAFY3QpYSb", signer: false, writable: true, }, { pubkey: "AmcWF1RdEB4dAxuevnpVG3cwHTYxbV8cz27c1qT5dddr", signer: false, writable: true, }, { pubkey: "D3wgcpWjAWR3GREbkyuGr3bNLHfdQsLr5hN2AvSP8pBi", signer: false, writable: true, }, { pubkey: "J9qZY93eS6Du1E8K6zNqAs71YeAiBncUywmuCbF1Wwei", signer: false, writable: true, }, { pubkey: "67dNFe4z58pmTs1DshwTm2rT127XtBCeRaBxDUYwaLfu", signer: false, writable: true, }, { pubkey: "14Cc7DA6MwpNdAZZYdLxK6WQ9meMaeLX1WsCyLRf5nqw", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "B7dtJwRwGnx5hMA8uDQuk4cxHGR4sF843FTME4Jr2ft2", signer: false, writable: false, }, { pubkey: "5QY6DGcNE7rCW6ReRJSfiq9KF8wmyESbhiiLwvJT1YWy", signer: false, writable: false, }, { pubkey: "4pUQS4Jo2dsfWzt3VgHXy3H6RYnEDd11oWPiaM2rdAPw", signer: false, writable: false, }, { pubkey: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", signer: false, writable: false, }, { pubkey: "HZaWndaNWHFDd9Dhk5pqUUtsmoBCqzb1MLu3NAh1VX6B", signer: false, writable: false, }, ], instructions: [ { parsed: { info: { account: "5x13F4NupczfwP9EjJP4wcDQWinhUk2wXNeS1xYMzAgR", mint: "14Cc7DA6MwpNdAZZYdLxK6WQ9meMaeLX1WsCyLRf5nqw", rentSysvar: "SysvarRent111111111111111111111111111111111", source: "CScUB4iBTfCWaFkj5gRpXx42HVpAgDvPJgbQxtETRXi1", systemProgram: "11111111111111111111111111111111", tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", wallet: "CScUB4iBTfCWaFkj5gRpXx42HVpAgDvPJgbQxtETRXi1", }, type: "create", }, program: "spl-associated-token-account", programId: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", }, { accounts: [ "CScUB4iBTfCWaFkj5gRpXx42HVpAgDvPJgbQxtETRXi1", "5x13F4NupczfwP9EjJP4wcDQWinhUk2wXNeS1xYMzAgR", "EDAWjyzq1Mf4JDue3tNiqhGeUg8az41EsHEQcEmjnZBY", "Gi44PdWS951cZjR5hgW1VnvKkxcV3scyHFpAFY3QpYSb", "AmcWF1RdEB4dAxuevnpVG3cwHTYxbV8cz27c1qT5dddr", "B7dtJwRwGnx5hMA8uDQuk4cxHGR4sF843FTME4Jr2ft2", "5QY6DGcNE7rCW6ReRJSfiq9KF8wmyESbhiiLwvJT1YWy", "14Cc7DA6MwpNdAZZYdLxK6WQ9meMaeLX1WsCyLRf5nqw", "4pUQS4Jo2dsfWzt3VgHXy3H6RYnEDd11oWPiaM2rdAPw", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "D3wgcpWjAWR3GREbkyuGr3bNLHfdQsLr5hN2AvSP8pBi", "J9qZY93eS6Du1E8K6zNqAs71YeAiBncUywmuCbF1Wwei", "67dNFe4z58pmTs1DshwTm2rT127XtBCeRaBxDUYwaLfu", ], data: "2UnMphP3bh8T", programId: "HZaWndaNWHFDd9Dhk5pqUUtsmoBCqzb1MLu3NAh1VX6B", }, ], recentBlockhash: "BBdpUZtu4nysqope7HrxBhSP6fauFgQ1ccSEe6b6UZzU", }, signatures: [ "4CwUFDv1JoaK4iN2chARePZZjAPrXdcX2VwDC2Snt4gNgdmFfqtiUR6HkniFNfLwh35rQzTjqhpDkgzWw69e6Svc", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/digitalEyesSaleTx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1635551628, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "8F81Yh4FbpGgPcCoxuJsDNaBwZW6JURp6yAvQFnhVhw6", lamports: 2039280, source: "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "8F81Yh4FbpGgPcCoxuJsDNaBwZW6JURp6yAvQFnhVhw6", space: 165, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "8F81Yh4FbpGgPcCoxuJsDNaBwZW6JURp6yAvQFnhVhw6", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "8F81Yh4FbpGgPcCoxuJsDNaBwZW6JURp6yAvQFnhVhw6", mint: "ECoNeXqLJofE7WZZzkntyTr3kqgrELmcLiY4HN9qb2ae", owner: "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, { index: 1, instructions: [ { parsed: { info: { destination: "3iYf9hHQPciwgJ1TCjpRUp1A3QW4AfaK7J6vCmETRMuu", lamports: 750000, source: "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "Zp66dczQGRNwpcRzpAN24SY1EhYU7c253HDKZw84YH9", lamports: 0, source: "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "3UCtQ8D24XviEujCNWpM7hQNqMHfqzat1XtJta6DhvhD", lamports: 0, source: "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "6EjCH2MQBucbfCXZbrUpP3jTkYLJi3r87rdyptrrNAXJ", lamports: 29250000, source: "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { amount: "1", destination: "8F81Yh4FbpGgPcCoxuJsDNaBwZW6JURp6yAvQFnhVhw6", multisigAuthority: "F4ghBzHFNgJxV4wEQDchU5i7n4XWWMBSaq7CuswGiVsr", signers: ["F4ghBzHFNgJxV4wEQDchU5i7n4XWWMBSaq7CuswGiVsr"], source: "G28rmTFZQwX38airfjtfowPk2gJqSdxyJWggkCBxZoJu", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { account: "G28rmTFZQwX38airfjtfowPk2gJqSdxyJWggkCBxZoJu", destination: "6EjCH2MQBucbfCXZbrUpP3jTkYLJi3r87rdyptrrNAXJ", multisigOwner: "F4ghBzHFNgJxV4wEQDchU5i7n4XWWMBSaq7CuswGiVsr", signers: ["F4ghBzHFNgJxV4wEQDchU5i7n4XWWMBSaq7CuswGiVsr"], }, type: "closeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]", "Program log: Transfer 2039280 lamports to the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the associated token account to the SPL Token program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Initialize the associated token account", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3449 of 179575 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 24523 of 200000 compute units", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success", "Program A7p8451ktDCHq5yYaHczeLMYsjRsAkzc3hCXcSrwYHU7 invoke [1]", "Program log: Instruction: Exchange", "Program log: amount: 1", 'Program log: sales tax recipients: passed:3iYf9hHQPciwgJ1TCjpRUp1A3QW4AfaK7J6vCmETRMuu / expected:"3iYf9hHQPciwgJ1TCjpRUp1A3QW4AfaK7J6vCmETRMuu"', "Program log: Transfering sales tax", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Checking metadata...", "Program log: Disbursing royalties...", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Transfering payment to initializer.", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Calling the token program to transfer tokens to the taker...", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3246 of 130231 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program log: Calling the token program to close pda's temp account...", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: CloseAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2422 of 123814 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program log: Closing the escrow account...", "Program A7p8451ktDCHq5yYaHczeLMYsjRsAkzc3hCXcSrwYHU7 consumed 79962 of 200000 compute units", "Program A7p8451ktDCHq5yYaHczeLMYsjRsAkzc3hCXcSrwYHU7 success", ], postBalances: [ 6630906551, 2039280, 0, 2443004876, 0, 1017119393853, 1461600, 5616720, 4572720, 1806098160, 1, 1089991680, 1, 92968990310, 898174080, 1141440, ], postTokenBalances: [ { accountIndex: 1, mint: "ECoNeXqLJofE7WZZzkntyTr3kqgrELmcLiY4HN9qb2ae", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], preBalances: [ 6662950831, 0, 2039280, 2410093916, 1621680, 1017118643853, 1461600, 5616720, 4572720, 1806098160, 1, 1089991680, 1, 92968990310, 898174080, 1141440, ], preTokenBalances: [ { accountIndex: 2, mint: "ECoNeXqLJofE7WZZzkntyTr3kqgrELmcLiY4HN9qb2ae", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 104209815, transaction: { message: { accountKeys: [ { pubkey: "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", signer: true, writable: true, }, { pubkey: "8F81Yh4FbpGgPcCoxuJsDNaBwZW6JURp6yAvQFnhVhw6", signer: false, writable: true, }, { pubkey: "G28rmTFZQwX38airfjtfowPk2gJqSdxyJWggkCBxZoJu", signer: false, writable: true, }, { pubkey: "6EjCH2MQBucbfCXZbrUpP3jTkYLJi3r87rdyptrrNAXJ", signer: false, writable: true, }, { pubkey: "BKcWGeoSu7fYJVTMBvPGdGc5L8uMctQ1GJ56H9q9jPdS", signer: false, writable: true, }, { pubkey: "3iYf9hHQPciwgJ1TCjpRUp1A3QW4AfaK7J6vCmETRMuu", signer: false, writable: true, }, { pubkey: "ECoNeXqLJofE7WZZzkntyTr3kqgrELmcLiY4HN9qb2ae", signer: false, writable: true, }, { pubkey: "2TrLT1Rj7yz9Kgbt7Y1VtSfvTNCnE2mnYyE5yP6VZyS9", signer: false, writable: true, }, { pubkey: "Zp66dczQGRNwpcRzpAN24SY1EhYU7c253HDKZw84YH9", signer: false, writable: true, }, { pubkey: "3UCtQ8D24XviEujCNWpM7hQNqMHfqzat1XtJta6DhvhD", signer: false, writable: true, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "F4ghBzHFNgJxV4wEQDchU5i7n4XWWMBSaq7CuswGiVsr", signer: false, writable: false, }, { pubkey: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", signer: false, writable: false, }, { pubkey: "A7p8451ktDCHq5yYaHczeLMYsjRsAkzc3hCXcSrwYHU7", signer: false, writable: false, }, ], instructions: [ { parsed: { info: { account: "8F81Yh4FbpGgPcCoxuJsDNaBwZW6JURp6yAvQFnhVhw6", mint: "ECoNeXqLJofE7WZZzkntyTr3kqgrELmcLiY4HN9qb2ae", rentSysvar: "SysvarRent111111111111111111111111111111111", source: "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", systemProgram: "11111111111111111111111111111111", tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", wallet: "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", }, type: "create", }, program: "spl-associated-token-account", programId: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", }, { accounts: [ "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", "8F81Yh4FbpGgPcCoxuJsDNaBwZW6JURp6yAvQFnhVhw6", "G28rmTFZQwX38airfjtfowPk2gJqSdxyJWggkCBxZoJu", "6EjCH2MQBucbfCXZbrUpP3jTkYLJi3r87rdyptrrNAXJ", "BKcWGeoSu7fYJVTMBvPGdGc5L8uMctQ1GJ56H9q9jPdS", "3iYf9hHQPciwgJ1TCjpRUp1A3QW4AfaK7J6vCmETRMuu", "ECoNeXqLJofE7WZZzkntyTr3kqgrELmcLiY4HN9qb2ae", "2TrLT1Rj7yz9Kgbt7Y1VtSfvTNCnE2mnYyE5yP6VZyS9", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "F4ghBzHFNgJxV4wEQDchU5i7n4XWWMBSaq7CuswGiVsr", "Zp66dczQGRNwpcRzpAN24SY1EhYU7c253HDKZw84YH9", "3UCtQ8D24XviEujCNWpM7hQNqMHfqzat1XtJta6DhvhD", ], data: "jzDsaTSmGkw", programId: "A7p8451ktDCHq5yYaHczeLMYsjRsAkzc3hCXcSrwYHU7", }, ], recentBlockhash: "GqE4a2j1VYCcKgKMRVMmT7aaNY88pwyxh8Cnscb8R7a1", }, signatures: [ "5DqZaNrvEKLLUupRTbt56eYG4f8U25uxYH4wCw5UevbEttkBLDJuF9927yacw7J74kTtWKC1xuyA1QBQRakh3cd1", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/exchangeArtSaleTx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1636465965, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "6482e33zrerYfhKAjPR2ncMSrH2tbTy5LDjdhB5PXzxd", lamports: 49750000, source: "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "BhrcD75cVC4Dpuqat6QP9MwAEeyBf8GFZ74iMzv41jTm", lamports: 0, source: "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "4QJzmvKWpneEgHDa99QCb4hWtAhxA6qfFNtYWAb8Cw93", lamports: 99500000, source: "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "7ZvteCjTjt5HxYbmxyzo9xMavDEXkNLUG6r6pJJXijvj", lamports: 99500000, source: "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "7A6AV8pMznyt9eBXGbnkcgbuKhStz3vDQvWcRBoYWV5R", lamports: 1741250000, source: "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { amount: "1", destination: "GzAM8LrsbDFHhmXkBsmUZ3aJad2G3y8XSJCMrfCXRqwb", multisigAuthority: "BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2", signers: ["BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2"], source: "4Nh4j5A9ukweW3e14LaxmRGWKGM3ePrVjDamJfTc5HpQ", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { account: "4Nh4j5A9ukweW3e14LaxmRGWKGM3ePrVjDamJfTc5HpQ", destination: "7A6AV8pMznyt9eBXGbnkcgbuKhStz3vDQvWcRBoYWV5R", multisigOwner: "BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2", signers: ["BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2"], }, type: "closeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program AmK5g2XcyptVLCFESBCJqoSfwV3znGoVYQnqEnaAZKWn invoke [1]", "Program log: Instruction: AcceptExchangeByTaker (amount: 1)", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3246 of 146259 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: CloseAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2422 of 140048 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program AmK5g2XcyptVLCFESBCJqoSfwV3znGoVYQnqEnaAZKWn consumed 63945 of 200000 compute units", "Program AmK5g2XcyptVLCFESBCJqoSfwV3znGoVYQnqEnaAZKWn success", ], postBalances: [ 242200763, 2039280, 0, 1759795401, 0, 23534995018, 4572720, 149500000, 149495000, 1461600, 5616720, 1089991680, 1, 119000000, 1461600, 1141440, ], postTokenBalances: [ { accountIndex: 1, mint: "GSG2UXwfv5EE1Ad62bCc3pWcgJy5NRdFYof9JyyFZDMS", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], preBalances: [ 2232205763, 2039280, 2039280, 14877481, 1628640, 23485245018, 4572720, 50000000, 49995000, 1461600, 5616720, 1089991680, 1, 119000000, 1461600, 1141440, ], preTokenBalances: [ { accountIndex: 1, mint: "GSG2UXwfv5EE1Ad62bCc3pWcgJy5NRdFYof9JyyFZDMS", uiTokenAmount: { amount: "0", decimals: 0, uiAmount: null, uiAmountString: "0", }, }, { accountIndex: 2, mint: "GSG2UXwfv5EE1Ad62bCc3pWcgJy5NRdFYof9JyyFZDMS", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 106028506, transaction: { message: { accountKeys: [ { pubkey: "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ", signer: true, writable: true, }, { pubkey: "GzAM8LrsbDFHhmXkBsmUZ3aJad2G3y8XSJCMrfCXRqwb", signer: false, writable: true, }, { pubkey: "4Nh4j5A9ukweW3e14LaxmRGWKGM3ePrVjDamJfTc5HpQ", signer: false, writable: true, }, { pubkey: "7A6AV8pMznyt9eBXGbnkcgbuKhStz3vDQvWcRBoYWV5R", signer: false, writable: true, }, { pubkey: "8UcHhLq4euUGidninfLDzbBEq9jnQRsMF9hHvPtW4dC4", signer: false, writable: true, }, { pubkey: "6482e33zrerYfhKAjPR2ncMSrH2tbTy5LDjdhB5PXzxd", signer: false, writable: true, }, { pubkey: "BhrcD75cVC4Dpuqat6QP9MwAEeyBf8GFZ74iMzv41jTm", signer: false, writable: true, }, { pubkey: "4QJzmvKWpneEgHDa99QCb4hWtAhxA6qfFNtYWAb8Cw93", signer: false, writable: true, }, { pubkey: "7ZvteCjTjt5HxYbmxyzo9xMavDEXkNLUG6r6pJJXijvj", signer: false, writable: true, }, { pubkey: "GSG2UXwfv5EE1Ad62bCc3pWcgJy5NRdFYof9JyyFZDMS", signer: false, writable: false, }, { pubkey: "FLUgjuKHWySQ5gnQxmqnvoeydHcLY8VdfjNbFrpvYLNR", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2", signer: false, writable: false, }, { pubkey: "9jd5tCY3JhjfSYSpgRzsgpoF5V52rNXYm4eRMfXeqUwR", signer: false, writable: false, }, { pubkey: "AmK5g2XcyptVLCFESBCJqoSfwV3znGoVYQnqEnaAZKWn", signer: false, writable: false, }, ], instructions: [ { accounts: [ "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ", "GzAM8LrsbDFHhmXkBsmUZ3aJad2G3y8XSJCMrfCXRqwb", "4Nh4j5A9ukweW3e14LaxmRGWKGM3ePrVjDamJfTc5HpQ", "7A6AV8pMznyt9eBXGbnkcgbuKhStz3vDQvWcRBoYWV5R", "8UcHhLq4euUGidninfLDzbBEq9jnQRsMF9hHvPtW4dC4", "6482e33zrerYfhKAjPR2ncMSrH2tbTy5LDjdhB5PXzxd", "GSG2UXwfv5EE1Ad62bCc3pWcgJy5NRdFYof9JyyFZDMS", "FLUgjuKHWySQ5gnQxmqnvoeydHcLY8VdfjNbFrpvYLNR", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2", "9jd5tCY3JhjfSYSpgRzsgpoF5V52rNXYm4eRMfXeqUwR", "BhrcD75cVC4Dpuqat6QP9MwAEeyBf8GFZ74iMzv41jTm", "4QJzmvKWpneEgHDa99QCb4hWtAhxA6qfFNtYWAb8Cw93", "7ZvteCjTjt5HxYbmxyzo9xMavDEXkNLUG6r6pJJXijvj", ], data: "jzDsaTSmGkw", programId: "AmK5g2XcyptVLCFESBCJqoSfwV3znGoVYQnqEnaAZKWn", }, ], recentBlockhash: "Cj3zXV6hkKDMRmAkgdfURo3acZ5h2W28LbariB3ZrFJh", }, signatures: [ "4WniSeFvZHsnZEDueeWhP18dUC9bGwZjoQ19RQq14796GCdb7WVRsTjK8AZCLLhL136p4J96minzfZcKVjY3fNAY", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/exchangeArtSaleTxV2.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1637139756, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "6oTEszeAVQwvFgUkcitipR865qQUAy3UQ5ys5rfNDXC6", lamports: 2039280, source: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "6oTEszeAVQwvFgUkcitipR865qQUAy3UQ5ys5rfNDXC6", space: 165, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "6oTEszeAVQwvFgUkcitipR865qQUAy3UQ5ys5rfNDXC6", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "6oTEszeAVQwvFgUkcitipR865qQUAy3UQ5ys5rfNDXC6", mint: "BtoorpGmtSydBtUfCaiHAEFPnE6Q4QKopTKrix6Ftcn2", owner: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, { index: 1, instructions: [ { parsed: { info: { destination: "6482e33zrerYfhKAjPR2ncMSrH2tbTy5LDjdhB5PXzxd", lamports: 5000000, source: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "2DXWoqh6dCp8VFWwuPszWXcWAnegaEMyT4UVgRMJJzQn", lamports: 0, source: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "8pJyixptCqPPLSkT9qqjMmJjAELdP8YiGsL1ihNmSsaE", lamports: 100000000, source: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "3Z6T94rMaTKjfdQb9ShunvMJ6C9LqDqEkfKBBeGArpzp", lamports: 95000000, source: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { amount: "1", destination: "6oTEszeAVQwvFgUkcitipR865qQUAy3UQ5ys5rfNDXC6", multisigAuthority: "BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2", signers: ["BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2"], source: "HukHCJmGZLG6BEr8MjjacEoeJzjiMuwX4Y5Q5Yyvm1Lo", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { account: "HukHCJmGZLG6BEr8MjjacEoeJzjiMuwX4Y5Q5Yyvm1Lo", destination: "3Z6T94rMaTKjfdQb9ShunvMJ6C9LqDqEkfKBBeGArpzp", multisigOwner: "BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2", signers: ["BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2"], }, type: "closeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]", "Program log: Transfer 2039280 lamports to the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the associated token account to the SPL Token program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Initialize the associated token account", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3449 of 179574 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 24524 of 200000 compute units", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success", "Program AmK5g2XcyptVLCFESBCJqoSfwV3znGoVYQnqEnaAZKWn invoke [1]", "Program log: Instruction: AcceptExchangeByTaker (amount: 1)", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: final seller fee basis points after PHBT: 5000.0", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3246 of 144566 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: CloseAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2422 of 138355 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program AmK5g2XcyptVLCFESBCJqoSfwV3znGoVYQnqEnaAZKWn consumed 65510 of 200000 compute units", "Program AmK5g2XcyptVLCFESBCJqoSfwV3znGoVYQnqEnaAZKWn success", ], postBalances: [ 3583436090, 2039280, 0, 178325906, 0, 92565366518, 4572720, 16484238885, 1461600, 1, 1089991680, 1009200, 5616720, 166000000, 898174080, 1141440, ], postTokenBalances: [ { accountIndex: 1, mint: "BtoorpGmtSydBtUfCaiHAEFPnE6Q4QKopTKrix6Ftcn2", owner: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], preBalances: [ 3785480370, 0, 2039280, 79657986, 1628640, 92560366518, 4572720, 16384238885, 1461600, 1, 1089991680, 1009200, 5616720, 166000000, 898174080, 1141440, ], preTokenBalances: [ { accountIndex: 2, mint: "BtoorpGmtSydBtUfCaiHAEFPnE6Q4QKopTKrix6Ftcn2", owner: "BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 107304222, transaction: { message: { accountKeys: [ { pubkey: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", signer: true, writable: true, }, { pubkey: "6oTEszeAVQwvFgUkcitipR865qQUAy3UQ5ys5rfNDXC6", signer: false, writable: true, }, { pubkey: "HukHCJmGZLG6BEr8MjjacEoeJzjiMuwX4Y5Q5Yyvm1Lo", signer: false, writable: true, }, { pubkey: "3Z6T94rMaTKjfdQb9ShunvMJ6C9LqDqEkfKBBeGArpzp", signer: false, writable: true, }, { pubkey: "BjEdwXRGZh6NLk99P5utngc5Wed7UHYgxHBSQStq4o54", signer: false, writable: true, }, { pubkey: "6482e33zrerYfhKAjPR2ncMSrH2tbTy5LDjdhB5PXzxd", signer: false, writable: true, }, { pubkey: "2DXWoqh6dCp8VFWwuPszWXcWAnegaEMyT4UVgRMJJzQn", signer: false, writable: true, }, { pubkey: "8pJyixptCqPPLSkT9qqjMmJjAELdP8YiGsL1ihNmSsaE", signer: false, writable: true, }, { pubkey: "BtoorpGmtSydBtUfCaiHAEFPnE6Q4QKopTKrix6Ftcn2", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "CiFhuzidkjaxprBVPAENEpoRJsGkcxXnv2SNLPktYy7B", signer: false, writable: false, }, { pubkey: "BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2", signer: false, writable: false, }, { pubkey: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", signer: false, writable: false, }, { pubkey: "AmK5g2XcyptVLCFESBCJqoSfwV3znGoVYQnqEnaAZKWn", signer: false, writable: false, }, ], instructions: [ { parsed: { info: { account: "6oTEszeAVQwvFgUkcitipR865qQUAy3UQ5ys5rfNDXC6", mint: "BtoorpGmtSydBtUfCaiHAEFPnE6Q4QKopTKrix6Ftcn2", rentSysvar: "SysvarRent111111111111111111111111111111111", source: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", systemProgram: "11111111111111111111111111111111", tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", wallet: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", }, type: "create", }, program: "spl-associated-token-account", programId: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", }, { accounts: [ "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", "6oTEszeAVQwvFgUkcitipR865qQUAy3UQ5ys5rfNDXC6", "HukHCJmGZLG6BEr8MjjacEoeJzjiMuwX4Y5Q5Yyvm1Lo", "3Z6T94rMaTKjfdQb9ShunvMJ6C9LqDqEkfKBBeGArpzp", "BjEdwXRGZh6NLk99P5utngc5Wed7UHYgxHBSQStq4o54", "6482e33zrerYfhKAjPR2ncMSrH2tbTy5LDjdhB5PXzxd", "BtoorpGmtSydBtUfCaiHAEFPnE6Q4QKopTKrix6Ftcn2", "CiFhuzidkjaxprBVPAENEpoRJsGkcxXnv2SNLPktYy7B", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "BjaNzGdwRcFYeQGfuLYsc1BbaNRG1yxyWs1hZuGRT8J2", "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", "2DXWoqh6dCp8VFWwuPszWXcWAnegaEMyT4UVgRMJJzQn", "8pJyixptCqPPLSkT9qqjMmJjAELdP8YiGsL1ihNmSsaE", ], data: "jzDsaTSmGkw", programId: "AmK5g2XcyptVLCFESBCJqoSfwV3znGoVYQnqEnaAZKWn", }, ], recentBlockhash: "784RVPH2bwcPFdAjA3ozdeYFTgWTkAQtD5q6zcsPikty", }, signatures: [ "496U5Ric72tCEwDVekapUVqCGrHEeSTpA9wsn88R65nT8hZbuEZS5sjgn5iT4mnmSKbSNcTf4Q7Bdu2hyjWcqaAD", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/magicEdenFailedTx.ts ================================================ import {ParsedConfirmedTransaction} from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { "blockTime": 1646744640, "meta": { "err": {"InstructionError": [0, {"Custom": 1}]}, "fee": 5000, "innerInstructions": [{ "index": 0, "instructions": [{ "parsed": { "info": { "lamports": 2011440, "newAccount": "AXz5FXk9xuSj4dL5SCQTezPXL6rNZwqKyV8aWHTtf5s1", "owner": "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K", "source": "L9xDD9dUAcM8r5NHF6SJZRtd4FBpiDUJCbkKF2msWeL", "space": 161 }, "type": "createAccount" }, "program": "system", "programId": "11111111111111111111111111111111" }, { "parsed": { "info": { "destination": "7NcXXsn5MBUi3nfaE8VMJeZEUFnzcc9btHCFTHBoyrzG", "lamports": 199000000000, "source": "L9xDD9dUAcM8r5NHF6SJZRtd4FBpiDUJCbkKF2msWeL" }, "type": "transfer" }, "program": "system", "programId": "11111111111111111111111111111111" }] }], "logMessages": ["Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K invoke [1]", "Program log: Instruction: Buy", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Transfer: insufficient lamports 535541880, need 199000000000", "Program 11111111111111111111111111111111 failed: custom program error: 0x1", "Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K consumed 31706 of 200000 compute units", "Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K failed: custom program error: 0x1"], "postBalances": [537553320, 0, 100148868680, 0, 4679361921, 2039280, 0, 622546587905, 2234160, 122636106118, 183253627269, 21196708033, 7189216410, 1057098000, 1, 1461600, 5616720, 3654000, 953185920, 1009200, 898174080, 58542103680, 1141440], "postTokenBalances": [{ "accountIndex": 5, "mint": "HrMZjUm31CANQdP61abasiMvYpEYc8dAtuDNxWmzZSkq", "owner": "1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix", "uiTokenAmount": {"amount": "1", "decimals": 0, "uiAmount": 1.0, "uiAmountString": "1"} }], "preBalances": [537558320, 0, 100148868680, 0, 4679361921, 2039280, 0, 622546587905, 2234160, 122636106118, 183253627269, 21196708033, 7189216410, 1057098000, 1, 1461600, 5616720, 3654000, 953185920, 1009200, 898174080, 58542103680, 1141440], "preTokenBalances": [{ "accountIndex": 5, "mint": "HrMZjUm31CANQdP61abasiMvYpEYc8dAtuDNxWmzZSkq", "owner": "1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix", "uiTokenAmount": {"amount": "1", "decimals": 0, "uiAmount": 1.0, "uiAmountString": "1"} }], "rewards": [], "status": {"Err": {"InstructionError": [0, {"Custom": 1}]}} }, "slot": 124028515, "transaction": { "message": { "accountKeys": [{ "pubkey": "L9xDD9dUAcM8r5NHF6SJZRtd4FBpiDUJCbkKF2msWeL", "signer": true, "writable": true }, { "pubkey": "7NcXXsn5MBUi3nfaE8VMJeZEUFnzcc9btHCFTHBoyrzG", "signer": false, "writable": true }, { "pubkey": "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "signer": false, "writable": true }, { "pubkey": "AXz5FXk9xuSj4dL5SCQTezPXL6rNZwqKyV8aWHTtf5s1", "signer": false, "writable": true }, { "pubkey": "Dga1gJnASog3uDjjibVkqvbtfbvrj9Hz3v2uN1Vojaid", "signer": false, "writable": true }, { "pubkey": "91suNRSJkMbTtNj7U7oQUxQ4TEu9jHJEiFAY3RTU8BUx", "signer": false, "writable": true }, { "pubkey": "6i9pirs3gRj1XsGVks3SHsQcnoAES2mwFYmhKAkexgYw", "signer": false, "writable": true }, { "pubkey": "rFqFJ9g7TGBD8Ed7TPDnvGKZ5pWLPDyxLcvcH2eRCtt", "signer": false, "writable": true }, { "pubkey": "2mxszBFYzWnwUN3MsYf96ENtNXRFtxE66rVR71j2gTpi", "signer": false, "writable": true }, { "pubkey": "9BKWqDHfHZh9j39xakYVMdr6hXmCLHH5VfCpeq2idU9L", "signer": false, "writable": true }, { "pubkey": "9FYsKrNuEweb55Wa2jaj8wTKYDBvuCG3huhakEj96iN9", "signer": false, "writable": true }, { "pubkey": "HNGVuL5kqjDehw7KR63w9gxow32sX6xzRNgLb8GkbwCM", "signer": false, "writable": true }, { "pubkey": "7FzXBBPjzrNJbm9MrZKZcyvP3ojVeYPUG2XkBPVZvuBu", "signer": false, "writable": true }, { "pubkey": "DC2mkgwhy56w3viNtHDjJQmc7SGu2QX785bS4aexojwX", "signer": false, "writable": true }, { "pubkey": "11111111111111111111111111111111", "signer": false, "writable": false }, { "pubkey": "HrMZjUm31CANQdP61abasiMvYpEYc8dAtuDNxWmzZSkq", "signer": false, "writable": false }, { "pubkey": "57wdSxZi3tA2jfFKvjaZbbkFR5G9yj51QbuHgbsunCTt", "signer": false, "writable": false }, { "pubkey": "E8cU1WiRWjanGxmn96ewBgk9vPTcL6AEZ1t6F6fkgUWe", "signer": false, "writable": false }, { "pubkey": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "signer": false, "writable": false }, { "pubkey": "SysvarRent111111111111111111111111111111111", "signer": false, "writable": false }, { "pubkey": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", "signer": false, "writable": false }, { "pubkey": "1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix", "signer": false, "writable": false }, { "pubkey": "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K", "signer": false, "writable": false }], "instructions": [{ "accounts": ["L9xDD9dUAcM8r5NHF6SJZRtd4FBpiDUJCbkKF2msWeL", "11111111111111111111111111111111", "HrMZjUm31CANQdP61abasiMvYpEYc8dAtuDNxWmzZSkq", "57wdSxZi3tA2jfFKvjaZbbkFR5G9yj51QbuHgbsunCTt", "7NcXXsn5MBUi3nfaE8VMJeZEUFnzcc9btHCFTHBoyrzG", "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "E8cU1WiRWjanGxmn96ewBgk9vPTcL6AEZ1t6F6fkgUWe", "AXz5FXk9xuSj4dL5SCQTezPXL6rNZwqKyV8aWHTtf5s1", "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "SysvarRent111111111111111111111111111111111"], "data": "3Jmjmsq2jyrch5iuumKthq9BpAtbcaJp3dQRuTsmCFqy3Bu", "programId": "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K" }, { "accounts": ["L9xDD9dUAcM8r5NHF6SJZRtd4FBpiDUJCbkKF2msWeL", "Dga1gJnASog3uDjjibVkqvbtfbvrj9Hz3v2uN1Vojaid", "11111111111111111111111111111111", "91suNRSJkMbTtNj7U7oQUxQ4TEu9jHJEiFAY3RTU8BUx", "HrMZjUm31CANQdP61abasiMvYpEYc8dAtuDNxWmzZSkq", "57wdSxZi3tA2jfFKvjaZbbkFR5G9yj51QbuHgbsunCTt", "7NcXXsn5MBUi3nfaE8VMJeZEUFnzcc9btHCFTHBoyrzG", "6i9pirs3gRj1XsGVks3SHsQcnoAES2mwFYmhKAkexgYw", "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "E8cU1WiRWjanGxmn96ewBgk9vPTcL6AEZ1t6F6fkgUWe", "rFqFJ9g7TGBD8Ed7TPDnvGKZ5pWLPDyxLcvcH2eRCtt", "AXz5FXk9xuSj4dL5SCQTezPXL6rNZwqKyV8aWHTtf5s1", "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "2mxszBFYzWnwUN3MsYf96ENtNXRFtxE66rVR71j2gTpi", "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", "1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix", "SysvarRent111111111111111111111111111111111", "9BKWqDHfHZh9j39xakYVMdr6hXmCLHH5VfCpeq2idU9L", "9FYsKrNuEweb55Wa2jaj8wTKYDBvuCG3huhakEj96iN9", "HNGVuL5kqjDehw7KR63w9gxow32sX6xzRNgLb8GkbwCM", "7FzXBBPjzrNJbm9MrZKZcyvP3ojVeYPUG2XkBPVZvuBu", "DC2mkgwhy56w3viNtHDjJQmc7SGu2QX785bS4aexojwX"], "data": "d6iteQtSVrfiCnAFBCZVgGJni4MkYHGWFMcA4f3DWT4LEbK7SgUwCTKy8", "programId": "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K" }], "recentBlockhash": "GkuTfjHCRufeew6yCoVbuEmTiNkY82X6R8dqSE5qiGgm" }, "signatures": ["5D3kshpCeGwhxBBPRQXmD48XvENJKXSwR79v6ceZBRAS41d2JeqMv3d2Yy9aZ1LADwQdDiop4ErRihnfYudfRJBy"] } } export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/magicEdenSaleFromBidTx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1640678496, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "2NZukH2TXpcuZP4htiuT8CFxcaQSWzkkR6kepSWnZ24Q", lamports: 17000000, source: "2aAcGP4Ls74XKAkFXKfFfw7CaJpHrPWcz6EaNcptWHhe", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "4eQwMqAA4c2VUD51rqfAke7kqeFLAxcxSB67rtFjDyZA", lamports: 17000000, source: "2aAcGP4Ls74XKAkFXKfFfw7CaJpHrPWcz6EaNcptWHhe", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "Dz9kwoBVVzF11cHeKotQpA7t4aeCQsgRpVw4dg8zkntg", lamports: 17000000, source: "2aAcGP4Ls74XKAkFXKfFfw7CaJpHrPWcz6EaNcptWHhe", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "4xHEEswq2T2E5uNoa1uw34RNKzPerayBHxX3P4SaR7cD", lamports: 17000000, source: "2aAcGP4Ls74XKAkFXKfFfw7CaJpHrPWcz6EaNcptWHhe", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "33CJriD17bUScYW7eKFjM6BPfkFWPerHfdpvtw3a8JdN", lamports: 17000000, source: "2aAcGP4Ls74XKAkFXKfFfw7CaJpHrPWcz6EaNcptWHhe", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "HWZybKNqMa93EmHK2ESL2v1XShcnt4ma4nFf14497jNS", lamports: 17000000, source: "2aAcGP4Ls74XKAkFXKfFfw7CaJpHrPWcz6EaNcptWHhe", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "AJ3r8njrEnHnwmv2JmnXEYoy7EfsxWQq7UcnLUhjuVab", lamports: 748000000, source: "2aAcGP4Ls74XKAkFXKfFfw7CaJpHrPWcz6EaNcptWHhe", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "GvFvwYnoZGejJptANFYEhW29qEhYjHK5V1i1sV3b9PU9", authority: "GUfCR9mK6azb9vcpsxgXyj7XRPAKJd4KMHTTVvtncGgp", authorityType: "accountOwner", newAuthority: "2fT7A7iKwDodPj5rm4u4tXRFny9JY1ttHhHGp1PsvsAn", }, type: "setAuthority", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8 invoke [1]", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: SetAuthority", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2028 of 148416 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8 consumed 56397 of 200000 compute units", "Program MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8 success", ], postBalances: [ 3227874610, 179985000, 2039280, 0, 0, 0, 3318475293836, 338698861972, 11263045161, 7408400000, 107000000, 7406350720, 136218400423, 1, 1089991680, 5616720, 1141440, ], postTokenBalances: [ { accountIndex: 2, mint: "3SxS8hpvZ6BfHXwaURJAhtxXWbwnkUGA7HPV3b7uLnjN", owner: "2fT7A7iKwDodPj5rm4u4tXRFny9JY1ttHhHGp1PsvsAn", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], preBalances: [ 2478431930, 178071000, 2039280, 1914000, 850000000, 1447680, 3318458293836, 338681861972, 11246045161, 7391400000, 90000000, 7389350720, 136218400423, 1, 1089991680, 5616720, 1141440, ], preTokenBalances: [ { accountIndex: 2, mint: "3SxS8hpvZ6BfHXwaURJAhtxXWbwnkUGA7HPV3b7uLnjN", owner: "GUfCR9mK6azb9vcpsxgXyj7XRPAKJd4KMHTTVvtncGgp", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 113678983, transaction: { message: { accountKeys: [ { pubkey: "AJ3r8njrEnHnwmv2JmnXEYoy7EfsxWQq7UcnLUhjuVab", signer: true, writable: true, }, { pubkey: "2fT7A7iKwDodPj5rm4u4tXRFny9JY1ttHhHGp1PsvsAn", signer: false, writable: true, }, { pubkey: "GvFvwYnoZGejJptANFYEhW29qEhYjHK5V1i1sV3b9PU9", signer: false, writable: true, }, { pubkey: "3wbvVNnZaNDQRVqQetUt3pkpucmjM6Pa2JyR9Yy2GYzj", signer: false, writable: true, }, { pubkey: "2aAcGP4Ls74XKAkFXKfFfw7CaJpHrPWcz6EaNcptWHhe", signer: false, writable: true, }, { pubkey: "Hcot8D67Dod6B9D19FTeuuG8cuxjUzKEDWHUUcdZEENb", signer: false, writable: true, }, { pubkey: "2NZukH2TXpcuZP4htiuT8CFxcaQSWzkkR6kepSWnZ24Q", signer: false, writable: true, }, { pubkey: "4eQwMqAA4c2VUD51rqfAke7kqeFLAxcxSB67rtFjDyZA", signer: false, writable: true, }, { pubkey: "Dz9kwoBVVzF11cHeKotQpA7t4aeCQsgRpVw4dg8zkntg", signer: false, writable: true, }, { pubkey: "4xHEEswq2T2E5uNoa1uw34RNKzPerayBHxX3P4SaR7cD", signer: false, writable: true, }, { pubkey: "33CJriD17bUScYW7eKFjM6BPfkFWPerHfdpvtw3a8JdN", signer: false, writable: true, }, { pubkey: "HWZybKNqMa93EmHK2ESL2v1XShcnt4ma4nFf14497jNS", signer: false, writable: true, }, { pubkey: "GUfCR9mK6azb9vcpsxgXyj7XRPAKJd4KMHTTVvtncGgp", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "3F4Zwfm9Gz2UB1cB4sWsqHetzokkXFfw6VfbL15UCKcu", signer: false, writable: false, }, { pubkey: "MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8", signer: false, writable: false, }, ], instructions: [ { accounts: [ "AJ3r8njrEnHnwmv2JmnXEYoy7EfsxWQq7UcnLUhjuVab", "2fT7A7iKwDodPj5rm4u4tXRFny9JY1ttHhHGp1PsvsAn", "GvFvwYnoZGejJptANFYEhW29qEhYjHK5V1i1sV3b9PU9", "3wbvVNnZaNDQRVqQetUt3pkpucmjM6Pa2JyR9Yy2GYzj", "2aAcGP4Ls74XKAkFXKfFfw7CaJpHrPWcz6EaNcptWHhe", "Hcot8D67Dod6B9D19FTeuuG8cuxjUzKEDWHUUcdZEENb", "GUfCR9mK6azb9vcpsxgXyj7XRPAKJd4KMHTTVvtncGgp", "11111111111111111111111111111111", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "2NZukH2TXpcuZP4htiuT8CFxcaQSWzkkR6kepSWnZ24Q", "3F4Zwfm9Gz2UB1cB4sWsqHetzokkXFfw6VfbL15UCKcu", "4eQwMqAA4c2VUD51rqfAke7kqeFLAxcxSB67rtFjDyZA", "Dz9kwoBVVzF11cHeKotQpA7t4aeCQsgRpVw4dg8zkntg", "4xHEEswq2T2E5uNoa1uw34RNKzPerayBHxX3P4SaR7cD", "33CJriD17bUScYW7eKFjM6BPfkFWPerHfdpvtw3a8JdN", "HWZybKNqMa93EmHK2ESL2v1XShcnt4ma4nFf14497jNS", ], data: "RJ7YoBrhBjrzChhwrWvuLj", programId: "MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8", }, ], recentBlockhash: "4dvuRRQzcFYkGS9TqVPth94nK1p1n2HD9d9g3pKTsV3c", }, signatures: [ "1cSgCBgot6w4KevVvsZc2PiST16BsEh9KAvmnbsSC9xXvput4SXLoq5pneQfczQEBw3jjcdmupG7Gp6MjG5MLzy", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/magicEdenSaleTx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1635141315, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "2NZukH2TXpcuZP4htiuT8CFxcaQSWzkkR6kepSWnZ24Q", lamports: 74400000, source: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "4eQwMqAA4c2VUD51rqfAke7kqeFLAxcxSB67rtFjDyZA", lamports: 74400000, source: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "Dz9kwoBVVzF11cHeKotQpA7t4aeCQsgRpVw4dg8zkntg", lamports: 74400000, source: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "4xHEEswq2T2E5uNoa1uw34RNKzPerayBHxX3P4SaR7cD", lamports: 74400000, source: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "33CJriD17bUScYW7eKFjM6BPfkFWPerHfdpvtw3a8JdN", lamports: 74400000, source: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "HWZybKNqMa93EmHK2ESL2v1XShcnt4ma4nFf14497jNS", lamports: 74400000, source: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "HihC794BdNCetkizxdFjVD2KiKWirGYbm2ojvRYXQd6H", lamports: 3273600000, source: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "9m8xj63juQLQvSmWybzxxmShbnsf8tH29kkfRRKDBz2c", authority: "GUfCR9mK6azb9vcpsxgXyj7XRPAKJd4KMHTTVvtncGgp", authorityType: "accountOwner", newAuthority: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", }, type: "setAuthority", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8 invoke [1]", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: SetAuthority", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2028 of 156898 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8 consumed 47267 of 200000 compute units", "Program MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8 success", ], postBalances: [ 7687945720, 2039280, 3277943593, 0, 7767438857012, 344467027205, 8688759800, 5636600000, 497000000, 5634555720, 118399366401, 1, 1089991680, 5616720, 1141440, ], postTokenBalances: [ { accountIndex: 1, mint: "8pwYVy61QiSTJGPc8yYfkVPLBBr8r17WkpUFRhNK6cjK", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], preBalances: [ 11407950720, 2039280, 2895913, 1447680, 7767364457012, 344392627205, 8614359800, 5562200000, 422600000, 5560155720, 118399366401, 1, 1089991680, 5616720, 1141440, ], preTokenBalances: [ { accountIndex: 1, mint: "8pwYVy61QiSTJGPc8yYfkVPLBBr8r17WkpUFRhNK6cjK", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 103384246, transaction: { message: { accountKeys: [ { pubkey: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", signer: true, writable: true, }, { pubkey: "9m8xj63juQLQvSmWybzxxmShbnsf8tH29kkfRRKDBz2c", signer: false, writable: true, }, { pubkey: "HihC794BdNCetkizxdFjVD2KiKWirGYbm2ojvRYXQd6H", signer: false, writable: true, }, { pubkey: "DKoBZuFVfeVycjeb76M3nabuDx3zewTBbDr6mdCsUU1M", signer: false, writable: true, }, { pubkey: "2NZukH2TXpcuZP4htiuT8CFxcaQSWzkkR6kepSWnZ24Q", signer: false, writable: true, }, { pubkey: "4eQwMqAA4c2VUD51rqfAke7kqeFLAxcxSB67rtFjDyZA", signer: false, writable: true, }, { pubkey: "Dz9kwoBVVzF11cHeKotQpA7t4aeCQsgRpVw4dg8zkntg", signer: false, writable: true, }, { pubkey: "4xHEEswq2T2E5uNoa1uw34RNKzPerayBHxX3P4SaR7cD", signer: false, writable: true, }, { pubkey: "33CJriD17bUScYW7eKFjM6BPfkFWPerHfdpvtw3a8JdN", signer: false, writable: true, }, { pubkey: "HWZybKNqMa93EmHK2ESL2v1XShcnt4ma4nFf14497jNS", signer: false, writable: true, }, { pubkey: "GUfCR9mK6azb9vcpsxgXyj7XRPAKJd4KMHTTVvtncGgp", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "AJUb5pxdi4Bh4AeL6mHHqTjU5Up4x114Y9nyu7pkRMBc", signer: false, writable: false, }, { pubkey: "MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8", signer: false, writable: false, }, ], instructions: [ { accounts: [ "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", "9m8xj63juQLQvSmWybzxxmShbnsf8tH29kkfRRKDBz2c", "HihC794BdNCetkizxdFjVD2KiKWirGYbm2ojvRYXQd6H", "DKoBZuFVfeVycjeb76M3nabuDx3zewTBbDr6mdCsUU1M", "GUfCR9mK6azb9vcpsxgXyj7XRPAKJd4KMHTTVvtncGgp", "11111111111111111111111111111111", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "2NZukH2TXpcuZP4htiuT8CFxcaQSWzkkR6kepSWnZ24Q", "AJUb5pxdi4Bh4AeL6mHHqTjU5Up4x114Y9nyu7pkRMBc", "4eQwMqAA4c2VUD51rqfAke7kqeFLAxcxSB67rtFjDyZA", "Dz9kwoBVVzF11cHeKotQpA7t4aeCQsgRpVw4dg8zkntg", "4xHEEswq2T2E5uNoa1uw34RNKzPerayBHxX3P4SaR7cD", "33CJriD17bUScYW7eKFjM6BPfkFWPerHfdpvtw3a8JdN", "HWZybKNqMa93EmHK2ESL2v1XShcnt4ma4nFf14497jNS", ], data: "8s5SjQsS25V", programId: "MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8", }, ], recentBlockhash: "5heDujnNgj2hPUXa9iqRMxynQX5Z2tzXEkPn9wuagWSd", }, signatures: [ "626EgwuS6dbUKrkZujQCFjHiRsz92ALR5gNAEg2eMpZzEo88Cci6HifpDFcvgYR8j88nXUq1nRUA7UDRdvB7Y6WD", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/magicEdenSaleTxV2.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1643310376, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "4p8JyqkVHZHaNxuoXHKCf4G7HPCVQVAzkcrk3qWFYwbd", lamports: 800000000, source: "87QLcvBCVmfcKo8sVZfPEbRS8PzT9tsgmHuHxRvvrChv", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, ], }, { index: 1, instructions: [ { parsed: { info: { lamports: 2011440, newAccount: "CgbcZSgtCR3sRCXowNPxb7nY2qovJtx2gWHFFy4VxG7z", owner: "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K", source: "87QLcvBCVmfcKo8sVZfPEbRS8PzT9tsgmHuHxRvvrChv", space: 161, }, type: "createAccount", }, program: "system", programId: "11111111111111111111111111111111", }, ], }, { index: 2, instructions: [ { parsed: { info: { destination: "RRUMF9KYPcvNSmnicNMAFKx5wDYix3wjNa6bA7R6xqA", lamports: 4000000, source: "4p8JyqkVHZHaNxuoXHKCf4G7HPCVQVAzkcrk3qWFYwbd", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "Ao65TQeY33TvP8fF36cy8ykgoU8Mbamks4J5oCA8eEWj", lamports: 21600000, source: "4p8JyqkVHZHaNxuoXHKCf4G7HPCVQVAzkcrk3qWFYwbd", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "BEmqvnMVMDJWw4xN6q7jfnHNbfbgZmnmSQZFc2AfJtqP", lamports: 12400000, source: "4p8JyqkVHZHaNxuoXHKCf4G7HPCVQVAzkcrk3qWFYwbd", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "3m5x6yLrRsDHQp81jKDBNH1xfy89Wjgc5uiZSzrmdMcy", lamports: 2000000, source: "4p8JyqkVHZHaNxuoXHKCf4G7HPCVQVAzkcrk3qWFYwbd", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "rFqFJ9g7TGBD8Ed7TPDnvGKZ5pWLPDyxLcvcH2eRCtt", lamports: 16000000, source: "4p8JyqkVHZHaNxuoXHKCf4G7HPCVQVAzkcrk3qWFYwbd", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "FVftjwhGyfzcGfTGK8SU8E55E3dCod7rQc2fymaR9vTe", lamports: 744000000, source: "4p8JyqkVHZHaNxuoXHKCf4G7HPCVQVAzkcrk3qWFYwbd", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "BdhynZZn5qNNygMeqfZzwQAqdpcvsoPawVdECnQLorCA", mint: "5ygnoy84v2bqMw8iFLD4k3axQfF8wgKQtG6maTtgwojG", rentSysvar: "SysvarRent111111111111111111111111111111111", source: "87QLcvBCVmfcKo8sVZfPEbRS8PzT9tsgmHuHxRvvrChv", systemProgram: "11111111111111111111111111111111", tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", wallet: "87QLcvBCVmfcKo8sVZfPEbRS8PzT9tsgmHuHxRvvrChv", }, type: "create", }, program: "spl-associated-token-account", programId: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", }, { parsed: { info: { destination: "BdhynZZn5qNNygMeqfZzwQAqdpcvsoPawVdECnQLorCA", lamports: 2039280, source: "87QLcvBCVmfcKo8sVZfPEbRS8PzT9tsgmHuHxRvvrChv", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "BdhynZZn5qNNygMeqfZzwQAqdpcvsoPawVdECnQLorCA", space: 165, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "BdhynZZn5qNNygMeqfZzwQAqdpcvsoPawVdECnQLorCA", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "BdhynZZn5qNNygMeqfZzwQAqdpcvsoPawVdECnQLorCA", mint: "5ygnoy84v2bqMw8iFLD4k3axQfF8wgKQtG6maTtgwojG", owner: "87QLcvBCVmfcKo8sVZfPEbRS8PzT9tsgmHuHxRvvrChv", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { amount: "1", authority: "1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix", destination: "BdhynZZn5qNNygMeqfZzwQAqdpcvsoPawVdECnQLorCA", source: "3qdhuUJTFCb47hztH5PDGF9HTjqEAKDAF4dTHKVaehAL", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K invoke [1]", "Program log: Instruction: Deposit", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K consumed 10184 of 200000 compute units", "Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K success", "Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K invoke [1]", "Program log: Instruction: Buy", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K consumed 27510 of 200000 compute units", "Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K success", "Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K invoke [1]", "Program log: Instruction: ExecuteSale", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [2]", "Program log: Transfer 2039280 lamports to the associated token account", "Program 11111111111111111111111111111111 invoke [3]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the associated token account", "Program 11111111111111111111111111111111 invoke [3]", "Program 11111111111111111111111111111111 success", "Program log: Assign the associated token account to the SPL Token program", "Program 11111111111111111111111111111111 invoke [3]", "Program 11111111111111111111111111111111 success", "Program log: Initialize the associated token account", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3297 of 125376 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 24372 of 145802 compute units", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2712 of 116265 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K consumed 89981 of 200000 compute units", "Program M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K success", ], postBalances: [ 8279202731, 0, 7162913680, 0, 3147126730, 2039280, 2039280, 89956212927, 0, 4906800, 212378229132, 721447087, 3601185904, 24081502475, 1, 3654000, 1461600, 5616720, 953185920, 1009200, 898174080, 0, 1141440, ], postTokenBalances: [ { accountIndex: 5, mint: "5ygnoy84v2bqMw8iFLD4k3axQfF8wgKQtG6maTtgwojG", owner: "FVftjwhGyfzcGfTGK8SU8E55E3dCod7rQc2fymaR9vTe", uiTokenAmount: { amount: "0", decimals: 0, uiAmount: null, uiAmountString: "0", }, }, { accountIndex: 6, mint: "5ygnoy84v2bqMw8iFLD4k3axQfF8wgKQtG6maTtgwojG", owner: "87QLcvBCVmfcKo8sVZfPEbRS8PzT9tsgmHuHxRvvrChv", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], preBalances: [ 9081247011, 0, 7162913680, 0, 2400892570, 2039280, 0, 89940212927, 2234160, 4906800, 212374229132, 699847087, 3588785904, 24079502475, 1, 3654000, 1461600, 5616720, 953185920, 1009200, 898174080, 0, 1141440, ], preTokenBalances: [ { accountIndex: 5, mint: "5ygnoy84v2bqMw8iFLD4k3axQfF8wgKQtG6maTtgwojG", owner: "FVftjwhGyfzcGfTGK8SU8E55E3dCod7rQc2fymaR9vTe", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 118115018, transaction: { message: { accountKeys: [ { pubkey: "87QLcvBCVmfcKo8sVZfPEbRS8PzT9tsgmHuHxRvvrChv", signer: true, writable: true, }, { pubkey: "4p8JyqkVHZHaNxuoXHKCf4G7HPCVQVAzkcrk3qWFYwbd", signer: false, writable: true, }, { pubkey: "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", signer: false, writable: true, }, { pubkey: "CgbcZSgtCR3sRCXowNPxb7nY2qovJtx2gWHFFy4VxG7z", signer: false, writable: true, }, { pubkey: "FVftjwhGyfzcGfTGK8SU8E55E3dCod7rQc2fymaR9vTe", signer: false, writable: true, }, { pubkey: "3qdhuUJTFCb47hztH5PDGF9HTjqEAKDAF4dTHKVaehAL", signer: false, writable: true, }, { pubkey: "BdhynZZn5qNNygMeqfZzwQAqdpcvsoPawVdECnQLorCA", signer: false, writable: true, }, { pubkey: "rFqFJ9g7TGBD8Ed7TPDnvGKZ5pWLPDyxLcvcH2eRCtt", signer: false, writable: true, }, { pubkey: "9kDcWHT7brm8bX9UxH2JAbUHWrcsHaDRZwfGaXF63Nfy", signer: false, writable: true, }, { pubkey: "9sfttw8dc1j7RsSgiFdDyt1a1XyRT3BPgFqYCXysER5W", signer: false, writable: true, }, { pubkey: "RRUMF9KYPcvNSmnicNMAFKx5wDYix3wjNa6bA7R6xqA", signer: false, writable: true, }, { pubkey: "Ao65TQeY33TvP8fF36cy8ykgoU8Mbamks4J5oCA8eEWj", signer: false, writable: true, }, { pubkey: "BEmqvnMVMDJWw4xN6q7jfnHNbfbgZmnmSQZFc2AfJtqP", signer: false, writable: true, }, { pubkey: "3m5x6yLrRsDHQp81jKDBNH1xfy89Wjgc5uiZSzrmdMcy", signer: false, writable: true, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "E8cU1WiRWjanGxmn96ewBgk9vPTcL6AEZ1t6F6fkgUWe", signer: false, writable: false, }, { pubkey: "5ygnoy84v2bqMw8iFLD4k3axQfF8wgKQtG6maTtgwojG", signer: false, writable: false, }, { pubkey: "Bt1LrjGhVBhCvntA1Gaji6Lxcq75P314iX2UjjLsKcU9", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", signer: false, writable: false, }, { pubkey: "1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix", signer: false, writable: false, }, { pubkey: "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K", signer: false, writable: false, }, ], instructions: [ { accounts: [ "87QLcvBCVmfcKo8sVZfPEbRS8PzT9tsgmHuHxRvvrChv", "11111111111111111111111111111111", "4p8JyqkVHZHaNxuoXHKCf4G7HPCVQVAzkcrk3qWFYwbd", "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "E8cU1WiRWjanGxmn96ewBgk9vPTcL6AEZ1t6F6fkgUWe", "11111111111111111111111111111111", ], data: "3GyWrkssW12wSfxfrSBu6tNB", programId: "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K", }, { accounts: [ "87QLcvBCVmfcKo8sVZfPEbRS8PzT9tsgmHuHxRvvrChv", "11111111111111111111111111111111", "5ygnoy84v2bqMw8iFLD4k3axQfF8wgKQtG6maTtgwojG", "Bt1LrjGhVBhCvntA1Gaji6Lxcq75P314iX2UjjLsKcU9", "4p8JyqkVHZHaNxuoXHKCf4G7HPCVQVAzkcrk3qWFYwbd", "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "E8cU1WiRWjanGxmn96ewBgk9vPTcL6AEZ1t6F6fkgUWe", "CgbcZSgtCR3sRCXowNPxb7nY2qovJtx2gWHFFy4VxG7z", "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "SysvarRent111111111111111111111111111111111", ], data: "3Jmjmsq2jyrcnQkVCncXtJwWS92N2wHC7taajq9YRxu9oAX", programId: "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K", }, { accounts: [ "87QLcvBCVmfcKo8sVZfPEbRS8PzT9tsgmHuHxRvvrChv", "FVftjwhGyfzcGfTGK8SU8E55E3dCod7rQc2fymaR9vTe", "11111111111111111111111111111111", "3qdhuUJTFCb47hztH5PDGF9HTjqEAKDAF4dTHKVaehAL", "5ygnoy84v2bqMw8iFLD4k3axQfF8wgKQtG6maTtgwojG", "Bt1LrjGhVBhCvntA1Gaji6Lxcq75P314iX2UjjLsKcU9", "4p8JyqkVHZHaNxuoXHKCf4G7HPCVQVAzkcrk3qWFYwbd", "BdhynZZn5qNNygMeqfZzwQAqdpcvsoPawVdECnQLorCA", "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "E8cU1WiRWjanGxmn96ewBgk9vPTcL6AEZ1t6F6fkgUWe", "rFqFJ9g7TGBD8Ed7TPDnvGKZ5pWLPDyxLcvcH2eRCtt", "CgbcZSgtCR3sRCXowNPxb7nY2qovJtx2gWHFFy4VxG7z", "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "9kDcWHT7brm8bX9UxH2JAbUHWrcsHaDRZwfGaXF63Nfy", "autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", "1BWutmTvYPwDtmw9abTkS4Ssr8no61spGAvW1X6NDix", "SysvarRent111111111111111111111111111111111", "9sfttw8dc1j7RsSgiFdDyt1a1XyRT3BPgFqYCXysER5W", "RRUMF9KYPcvNSmnicNMAFKx5wDYix3wjNa6bA7R6xqA", "Ao65TQeY33TvP8fF36cy8ykgoU8Mbamks4J5oCA8eEWj", "BEmqvnMVMDJWw4xN6q7jfnHNbfbgZmnmSQZFc2AfJtqP", "3m5x6yLrRsDHQp81jKDBNH1xfy89Wjgc5uiZSzrmdMcy", ], data: "d6iteQtSVrfiCnAHGCJ6bGCdwTFPQJgyXsHyJ5txQNo2VSyZcK7PRfFFm", programId: "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K", }, ], recentBlockhash: "CR6v1SWMqsnBGkheEEhF64Tvc6TYabYdnRVPm8Kn6mL1", }, signatures: [ "J9kVpP5br8Q9wKNh2YPEZTDQtMLnLuCLEkRUgHvhhKYciVYq6XwF4imjrsNVhMY8Pw3wGkvY3AKW3qxtBisBp5v", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/openSeaBidTx.ts ================================================ import {ParsedConfirmedTransaction} from "@solana/web3.js"; const tx: ParsedConfirmedTransaction = { "blockTime": 1650079198, "meta": { "err": null, "fee": 10000, "innerInstructions": [{ "index": 0, "instructions": [{ "parsed": { "info": { "destination": "9QveoLZ4SA1JdFdmuLRE7cynvrpbuZq2a5vvvy4ry5VY", "lamports": 49000000, "source": "8x7qhXu8osWcJrQWmczNGN7HS8scnGJhdt4PXxGWu3S1" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }] }, { "index": 1, "instructions": [{ "parsed": { "info": { "destination": "Aiyx4xsfL3NkhVZVp4xWZmdP3dpxAUSmtFt1vLYBFrWp", "lamports": 897840, "source": "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "account": "Aiyx4xsfL3NkhVZVp4xWZmdP3dpxAUSmtFt1vLYBFrWp", "space": 1 }, "type": "allocate" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "account": "Aiyx4xsfL3NkhVZVp4xWZmdP3dpxAUSmtFt1vLYBFrWp", "owner": "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk" }, "type": "assign" }, "program": "system", "programId": {"_bn": "00"} }] }], "logMessages": ["Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: Deposit", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 20144 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: Buy", "Program log: Err(Custom(6013)), Ok(254), 254", "Program log: Transfer 897840 lamports to the new account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the account Aiyx4xsfL3NkhVZVp4xWZmdP3dpxAUSmtFt1vLYBFrWp", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the account to the owning program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Completed assignation!", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 56074 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success", "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success"], "postBalances": [34800744, 10489990000, 355090000, 102695402162, 897840, 152395037831, 4085520, 953185920, 1, 1009200, 2039280, 5616720, 1141440], "postTokenBalances": [{ "accountIndex": 10, "mint": "GGe6kTQRbFscLJ7ANeAVw6wNABMUnr1bVMT7fNn1aVxv", "owner": "6vuH8FisDk3HEYd4oJN7jPdcEaJXF9kQDWxTiTgqGX49", "uiTokenAmount": {"amount": "1", "decimals": 0, "uiAmount": 1, "uiAmountString": "1"} }], "preBalances": [84708584, 10489990000, 306090000, 102695402162, 0, 152395037831, 4085520, 953185920, 1, 1009200, 2039280, 5616720, 1141440], "preTokenBalances": [{ "accountIndex": 10, "mint": "GGe6kTQRbFscLJ7ANeAVw6wNABMUnr1bVMT7fNn1aVxv", "owner": "6vuH8FisDk3HEYd4oJN7jPdcEaJXF9kQDWxTiTgqGX49", "uiTokenAmount": {"amount": "1", "decimals": 0, "uiAmount": 1, "uiAmountString": "1"} }], "rewards": [], "status": {"Ok": null} }, "slot": 129938837, "transaction": { "message": { "accountKeys": [{ "pubkey": {"_bn": "76207c90c0971f18f0e64cd685ec9fa39f4be7474f08208824ac8bedc0aed202"}, "signer": true, "writable": true }, { "pubkey": {"_bn": "0c14ca16dab25717d8fe41d9ec2617cd3f5d7c986f19d87898707564f3c516a7"}, "signer": true, "writable": true }, { "pubkey": {"_bn": "7cfe84a8831eca82cfe41c9dadbdf237dd03da16d8f2d06d595c44e029c3be37"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "49c5e99524f07898034804274203258b3165710477bd5762d3d2d93ad0a4c3bf"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "907a6372423fbc0d005a18e2ff6bdb81f1b1b5f31b5ab7dfbfbfce66534a7b15"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "069b8857feab8184fb687f634618c035dac439dc1aeb3b5598a0f00000000001"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "2989d6a9ff6b2a168b81bed69f59efcb8172a8c663a80112cce020c86145700b"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "06ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "00"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "06a7d517192c5c51218cc94c3d4af17f58daee089ba1fd44e3dbd98a00000000"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "ed501c2bf970de1b601ff82e39383f1e6475d6c9361df6df0747441b9f08cb10"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "6e60c995754a2f14ec5ecd6c9a3788a86c2cd729bcf73b2d3f3cb062d1a7496c"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "0a6593863cba461564eae41373721546eb0151c9308276bbd4ad2a1c3a42107b"}, "signer": false, "writable": false }], "instructions": [{ "accounts": [{"_bn": "76207c90c0971f18f0e64cd685ec9fa39f4be7474f08208824ac8bedc0aed202"}, {"_bn": "76207c90c0971f18f0e64cd685ec9fa39f4be7474f08208824ac8bedc0aed202"}, {"_bn": "0c14ca16dab25717d8fe41d9ec2617cd3f5d7c986f19d87898707564f3c516a7"}, {"_bn": "7cfe84a8831eca82cfe41c9dadbdf237dd03da16d8f2d06d595c44e029c3be37"}, {"_bn": "069b8857feab8184fb687f634618c035dac439dc1aeb3b5598a0f00000000001"}, {"_bn": "0c14ca16dab25717d8fe41d9ec2617cd3f5d7c986f19d87898707564f3c516a7"}, {"_bn": "2989d6a9ff6b2a168b81bed69f59efcb8172a8c663a80112cce020c86145700b"}, {"_bn": "49c5e99524f07898034804274203258b3165710477bd5762d3d2d93ad0a4c3bf"}, {"_bn": "06ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9"}, {"_bn": "00"}, {"_bn": "06a7d517192c5c51218cc94c3d4af17f58daee089ba1fd44e3dbd98a00000000"}], "data": "3GyWrkssW12wRP8osktezmE7", "programId": {"_bn": "0a6593863cba461564eae41373721546eb0151c9308276bbd4ad2a1c3a42107b"} }, { "accounts": [{"_bn": "76207c90c0971f18f0e64cd685ec9fa39f4be7474f08208824ac8bedc0aed202"}, {"_bn": "76207c90c0971f18f0e64cd685ec9fa39f4be7474f08208824ac8bedc0aed202"}, {"_bn": "00"}, {"_bn": "069b8857feab8184fb687f634618c035dac439dc1aeb3b5598a0f00000000001"}, {"_bn": "ed501c2bf970de1b601ff82e39383f1e6475d6c9361df6df0747441b9f08cb10"}, {"_bn": "6e60c995754a2f14ec5ecd6c9a3788a86c2cd729bcf73b2d3f3cb062d1a7496c"}, {"_bn": "7cfe84a8831eca82cfe41c9dadbdf237dd03da16d8f2d06d595c44e029c3be37"}, {"_bn": "0c14ca16dab25717d8fe41d9ec2617cd3f5d7c986f19d87898707564f3c516a7"}, {"_bn": "2989d6a9ff6b2a168b81bed69f59efcb8172a8c663a80112cce020c86145700b"}, {"_bn": "49c5e99524f07898034804274203258b3165710477bd5762d3d2d93ad0a4c3bf"}, {"_bn": "907a6372423fbc0d005a18e2ff6bdb81f1b1b5f31b5ab7dfbfbfce66534a7b15"}, {"_bn": "06ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9"}, {"_bn": "00"}, {"_bn": "06a7d517192c5c51218cc94c3d4af17f58daee089ba1fd44e3dbd98a00000000"}], "data": "48CS5rNxJb9H9ojfQ1885A7vY8x2wmHZZadu", "programId": {"_bn": "0a6593863cba461564eae41373721546eb0151c9308276bbd4ad2a1c3a42107b"} }, { "parsed": { "info": { "destination": "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn", "lamports": 897840, "source": "8x7qhXu8osWcJrQWmczNGN7HS8scnGJhdt4PXxGWu3S1" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }], "recentBlockhash": "BbydjUpsFYLFdy2jfvq8HjwdQaVWpZga4WzdfA7jrWy5" }, "signatures": ["3pL9V7rUs9i9oriNDEAYjsEn4x53JXcgurED4JuQ5C53biw1LQNqvo5abBx7fa5LrkPbA2otVkiDRPaEZYe1XtFS", "2yxLqEUUXGdtEnSnULpRLDxDXejcXCZnQziLAAF1s7AxPqFsRr8jgBamqXhoGoE52z1APcsB5YNRLWLF9MECT8U7"] } } export default tx; ================================================ FILE: src/lib/marketplaces/__fixtures__/openSeaSale2Tx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1650205927, meta: { err: null, fee: 10000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { amount: "1", delegate: "HS2eL9WJbh7pA4i4veK3YDwhGLRjY3uKryvG1NbHRprj", owner: "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", source: "824CvcF9V7tNJM4hRMJkn4ZvKTH5LNriRaz3vti8y9sw", }, type: "approve", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { destination: "Gihc1SqWvPFvLtNuMoYzZmS5xt9PJhAENc41fzeJjhx3", lamports: 897840, source: "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "Gihc1SqWvPFvLtNuMoYzZmS5xt9PJhAENc41fzeJjhx3", space: 1, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "Gihc1SqWvPFvLtNuMoYzZmS5xt9PJhAENc41fzeJjhx3", owner: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, ], }, { index: 2, instructions: [ { parsed: { info: { destination: "pAHAKoTJsAAe2ZcvTZUxoYzuygVAFAmbYmJYdWT886r", lamports: 1795680, source: "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, ], }, { index: 5, instructions: [ { parsed: { info: { destination: "FP1Wcq6ptVY6Q2JkTgL2SyZdwpRFUZGw8HEBvE9Zyo7P", lamports: 2039280, source: "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "FP1Wcq6ptVY6Q2JkTgL2SyZdwpRFUZGw8HEBvE9Zyo7P", space: 165, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "FP1Wcq6ptVY6Q2JkTgL2SyZdwpRFUZGw8HEBvE9Zyo7P", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "FP1Wcq6ptVY6Q2JkTgL2SyZdwpRFUZGw8HEBvE9Zyo7P", mint: "CiRHyMF2zUdfqJ5x6ixQnDiPJw4CcWWGmdqS2YQiFd88", owner: "C4YZMGs9KfffEqoD6s4oB8r7ipvhJsaGCagKTi2ixN5C", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, { index: 6, instructions: [ { parsed: { info: { destination: "HPWFCze26yt86yu5V56w8dRSRNvsggJ9bNKwC9qfjBz", lamports: 17000000, source: "5xwPyXkfmJdmNhdAhsCxBiWdGLABtbuyw9MRAF5b1Z16", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "2Tbc5LX7NSb32jiHMQfLra2vxppM11acfpjQ4VUV6De3", lamports: 16500000, source: "5xwPyXkfmJdmNhdAhsCxBiWdGLABtbuyw9MRAF5b1Z16", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "3wxiFnooogeur15QFihkEWbJpbr56xSC6xZjBxUw3BVq", lamports: 16500000, source: "5xwPyXkfmJdmNhdAhsCxBiWdGLABtbuyw9MRAF5b1Z16", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "8mcjXbJ8j4VryYFNpcBCFS37Au8zVYU53WTVaruJWcKt", lamports: 25000000, source: "5xwPyXkfmJdmNhdAhsCxBiWdGLABtbuyw9MRAF5b1Z16", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", lamports: 925000000, source: "5xwPyXkfmJdmNhdAhsCxBiWdGLABtbuyw9MRAF5b1Z16", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { amount: "1", authority: "HS2eL9WJbh7pA4i4veK3YDwhGLRjY3uKryvG1NbHRprj", destination: "FP1Wcq6ptVY6Q2JkTgL2SyZdwpRFUZGw8HEBvE9Zyo7P", source: "824CvcF9V7tNJM4hRMJkn4ZvKTH5LNriRaz3vti8y9sw", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: Sell", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Approve", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2050 of 165822 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program log: Transfer 897840 lamports to the new account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the account Gihc1SqWvPFvLtNuMoYzZmS5xt9PJhAENc41fzeJjhx3", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the account to the owning program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Completed assignation!", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 60439 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success", "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: WithdrawFromFee", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 13348 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success", "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]", "Program log: Transfer 2039280 lamports to the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the associated token account to the SPL Token program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Initialize the associated token account", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3297 of 179469 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 24509 of 200000 compute units", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: ExecuteSale", "Program log: Err(Custom(6013)), Ok(253), 253", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2712 of 123845 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 82007 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success", ], postBalances: [ 1044053447, 10489990000, 2039280, 4085520, 102754659602, 0, 0, 426941640, 2039280, 0, 489304360448, 0, 4572720, 3543981044, 166821478461, 931289370, 5616720, 953185920, 1, 0, 1009200, 1461600, 152395037831, 898174080, 1141440, ], postTokenBalances: [ { accountIndex: 2, mint: "CiRHyMF2zUdfqJ5x6ixQnDiPJw4CcWWGmdqS2YQiFd88", owner: "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", uiTokenAmount: { amount: "0", decimals: 0, uiAmount: null, uiAmountString: "0", }, }, { accountIndex: 8, mint: "CiRHyMF2zUdfqJ5x6ixQnDiPJw4CcWWGmdqS2YQiFd88", owner: "C4YZMGs9KfffEqoD6s4oB8r7ipvhJsaGCagKTi2ixN5C", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1, uiAmountString: "1", }, }, ], preBalances: [ 121102727, 10489990000, 2039280, 4085520, 102754659602, 0, 0, 426043800, 0, 1000000000, 489279360448, 897840, 4572720, 3526981044, 166804978461, 914789370, 5616720, 953185920, 1, 0, 1009200, 1461600, 152395037831, 898174080, 1141440, ], preTokenBalances: [ { accountIndex: 2, mint: "CiRHyMF2zUdfqJ5x6ixQnDiPJw4CcWWGmdqS2YQiFd88", owner: "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 130155306, transaction: { message: { accountKeys: [ { pubkey: "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", signer: true, writable: true, }, { pubkey: "pAHAKoTJsAAe2ZcvTZUxoYzuygVAFAmbYmJYdWT886r", signer: true, writable: true, }, { pubkey: "824CvcF9V7tNJM4hRMJkn4ZvKTH5LNriRaz3vti8y9sw", signer: false, writable: true, }, { pubkey: "3o9d13qUvEuuauhFrVom1vuCzgNsJifeaBYDPquaT73Y", signer: false, writable: true, }, { pubkey: "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn", signer: false, writable: true, }, { pubkey: "Gihc1SqWvPFvLtNuMoYzZmS5xt9PJhAENc41fzeJjhx3", signer: false, writable: true, }, { pubkey: "4JR3h5EnSg2teCjNLUQBUf4oXFEkZMwQCGBqpvGgfTt5", signer: false, writable: true, }, { pubkey: "C4YZMGs9KfffEqoD6s4oB8r7ipvhJsaGCagKTi2ixN5C", signer: false, writable: true, }, { pubkey: "FP1Wcq6ptVY6Q2JkTgL2SyZdwpRFUZGw8HEBvE9Zyo7P", signer: false, writable: true, }, { pubkey: "5xwPyXkfmJdmNhdAhsCxBiWdGLABtbuyw9MRAF5b1Z16", signer: false, writable: true, }, { pubkey: "8mcjXbJ8j4VryYFNpcBCFS37Au8zVYU53WTVaruJWcKt", signer: false, writable: true, }, { pubkey: "5ssHxeeehmY5y3C8RZeB5YmxXFC5cgNwtxhBhxW7BnC3", signer: false, writable: true, }, { pubkey: "86V3AnzroujF3SF6jSzzN5BJxiJ2BVh86x3p6uRYcg1k", signer: false, writable: true, }, { pubkey: "HPWFCze26yt86yu5V56w8dRSRNvsggJ9bNKwC9qfjBz", signer: false, writable: true, }, { pubkey: "2Tbc5LX7NSb32jiHMQfLra2vxppM11acfpjQ4VUV6De3", signer: false, writable: true, }, { pubkey: "3wxiFnooogeur15QFihkEWbJpbr56xSC6xZjBxUw3BVq", signer: false, writable: true, }, { pubkey: "EBDvjxNibXpXz3euMqcmLMwf5gWcFJKD88jxsZ16ttkg", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "HS2eL9WJbh7pA4i4veK3YDwhGLRjY3uKryvG1NbHRprj", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "CiRHyMF2zUdfqJ5x6ixQnDiPJw4CcWWGmdqS2YQiFd88", signer: false, writable: false, }, { pubkey: "So11111111111111111111111111111111111111112", signer: false, writable: false, }, { pubkey: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", signer: false, writable: false, }, { pubkey: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", signer: false, writable: false, }, ], instructions: [ { accounts: [ "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", "824CvcF9V7tNJM4hRMJkn4ZvKTH5LNriRaz3vti8y9sw", "EBDvjxNibXpXz3euMqcmLMwf5gWcFJKD88jxsZ16ttkg", "pAHAKoTJsAAe2ZcvTZUxoYzuygVAFAmbYmJYdWT886r", "3o9d13qUvEuuauhFrVom1vuCzgNsJifeaBYDPquaT73Y", "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn", "Gihc1SqWvPFvLtNuMoYzZmS5xt9PJhAENc41fzeJjhx3", "4JR3h5EnSg2teCjNLUQBUf4oXFEkZMwQCGBqpvGgfTt5", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "HS2eL9WJbh7pA4i4veK3YDwhGLRjY3uKryvG1NbHRprj", "SysvarRent111111111111111111111111111111111", ], data: "81r6u24fHZhKyc6M2WCR5XYgv31RuV6rV1Wdd", programId: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", }, { parsed: { info: { destination: "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn", lamports: 897840, source: "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { accounts: [ "pAHAKoTJsAAe2ZcvTZUxoYzuygVAFAmbYmJYdWT886r", "pAHAKoTJsAAe2ZcvTZUxoYzuygVAFAmbYmJYdWT886r", "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn", "3o9d13qUvEuuauhFrVom1vuCzgNsJifeaBYDPquaT73Y", "11111111111111111111111111111111", ], data: "PCrWfhudhPULPQhY2paGG7", programId: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", }, { parsed: { info: { destination: "C4YZMGs9KfffEqoD6s4oB8r7ipvhJsaGCagKTi2ixN5C", lamports: 897840, source: "pAHAKoTJsAAe2ZcvTZUxoYzuygVAFAmbYmJYdWT886r", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", lamports: 897840, source: "pAHAKoTJsAAe2ZcvTZUxoYzuygVAFAmbYmJYdWT886r", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "FP1Wcq6ptVY6Q2JkTgL2SyZdwpRFUZGw8HEBvE9Zyo7P", mint: "CiRHyMF2zUdfqJ5x6ixQnDiPJw4CcWWGmdqS2YQiFd88", rentSysvar: "SysvarRent111111111111111111111111111111111", source: "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", systemProgram: "11111111111111111111111111111111", tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", wallet: "C4YZMGs9KfffEqoD6s4oB8r7ipvhJsaGCagKTi2ixN5C", }, type: "create", }, program: "spl-associated-token-account", programId: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", }, { accounts: [ "C4YZMGs9KfffEqoD6s4oB8r7ipvhJsaGCagKTi2ixN5C", "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", "824CvcF9V7tNJM4hRMJkn4ZvKTH5LNriRaz3vti8y9sw", "CiRHyMF2zUdfqJ5x6ixQnDiPJw4CcWWGmdqS2YQiFd88", "EBDvjxNibXpXz3euMqcmLMwf5gWcFJKD88jxsZ16ttkg", "So11111111111111111111111111111111111111112", "5xwPyXkfmJdmNhdAhsCxBiWdGLABtbuyw9MRAF5b1Z16", "GHpmaYCQpsHdia7qJLzSANwCXjQGhBaqrjcJkQF1WxhA", "FP1Wcq6ptVY6Q2JkTgL2SyZdwpRFUZGw8HEBvE9Zyo7P", "pAHAKoTJsAAe2ZcvTZUxoYzuygVAFAmbYmJYdWT886r", "3o9d13qUvEuuauhFrVom1vuCzgNsJifeaBYDPquaT73Y", "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn", "8mcjXbJ8j4VryYFNpcBCFS37Au8zVYU53WTVaruJWcKt", "5ssHxeeehmY5y3C8RZeB5YmxXFC5cgNwtxhBhxW7BnC3", "Gihc1SqWvPFvLtNuMoYzZmS5xt9PJhAENc41fzeJjhx3", "4JR3h5EnSg2teCjNLUQBUf4oXFEkZMwQCGBqpvGgfTt5", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", "HS2eL9WJbh7pA4i4veK3YDwhGLRjY3uKryvG1NbHRprj", "SysvarRent111111111111111111111111111111111", "86V3AnzroujF3SF6jSzzN5BJxiJ2BVh86x3p6uRYcg1k", "HPWFCze26yt86yu5V56w8dRSRNvsggJ9bNKwC9qfjBz", "2Tbc5LX7NSb32jiHMQfLra2vxppM11acfpjQ4VUV6De3", "3wxiFnooogeur15QFihkEWbJpbr56xSC6xZjBxUw3BVq", ], data: "63LNsZWnP5nH22SwowudszNaWWQ2mDpCq9cKZ", programId: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", }, ], recentBlockhash: "5VqXz3JW6UhvSZ9KgyPy72afwU76seJ61E4FeeBVBJmc", }, signatures: [ "4frBMA4q4i11YxxpqNhFaygRuC6wa1XW8KHJwMWCCp3C6piXAWmSGinot7XiBXPqTTcnLGJkgag9Kvuz4gkiMrnX", "4VjEjpyUVtZuaBUFkjP9uCZKVMc7xGeuYmvwd8swgTWZ6cEWafnmAz2Qjr92ewMYwzhSZJ7daJ4xxSNkSjT6zGG8", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/openSeaSale3Tx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1650281847, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "5qXGXK96DDm8tYGcH1Er5RVLKLMtHxxsJWYKjuScD1Vp", lamports: 99000000000, source: "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "7CJBzeZi6Zcben2iKLe7L1XrYfgNagk9hHdijtJpqsYe", lamports: 897840, source: "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "7CJBzeZi6Zcben2iKLe7L1XrYfgNagk9hHdijtJpqsYe", space: 1, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "7CJBzeZi6Zcben2iKLe7L1XrYfgNagk9hHdijtJpqsYe", owner: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, ], }, { index: 1, instructions: [ { parsed: { info: { destination: "GVnaCFMZtnX91PZtGQ8J6MxNQoKf8XyvLPtv4BYBykHX", lamports: 2763120, source: "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "GVnaCFMZtnX91PZtGQ8J6MxNQoKf8XyvLPtv4BYBykHX", space: 269, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "GVnaCFMZtnX91PZtGQ8J6MxNQoKf8XyvLPtv4BYBykHX", owner: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, ], }, { index: 2, instructions: [ { parsed: { info: { destination: "9BKWqDHfHZh9j39xakYVMdr6hXmCLHH5VfCpeq2idU9L", lamports: 1621620000, source: "5qXGXK96DDm8tYGcH1Er5RVLKLMtHxxsJWYKjuScD1Vp", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "9FYsKrNuEweb55Wa2jaj8wTKYDBvuCG3huhakEj96iN9", lamports: 1039500000, source: "5qXGXK96DDm8tYGcH1Er5RVLKLMtHxxsJWYKjuScD1Vp", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "HNGVuL5kqjDehw7KR63w9gxow32sX6xzRNgLb8GkbwCM", lamports: 1039500000, source: "5qXGXK96DDm8tYGcH1Er5RVLKLMtHxxsJWYKjuScD1Vp", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "7FzXBBPjzrNJbm9MrZKZcyvP3ojVeYPUG2XkBPVZvuBu", lamports: 415800000, source: "5qXGXK96DDm8tYGcH1Er5RVLKLMtHxxsJWYKjuScD1Vp", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "DC2mkgwhy56w3viNtHDjJQmc7SGu2QX785bS4aexojwX", lamports: 41580000, source: "5qXGXK96DDm8tYGcH1Er5RVLKLMtHxxsJWYKjuScD1Vp", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "2e3dJ3mEjpdMDZsL5rGuCkMxqE116nBpMS2tKu9v8RRB", lamports: 2970000000, source: "5qXGXK96DDm8tYGcH1Er5RVLKLMtHxxsJWYKjuScD1Vp", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "AYfUa1MUjjivuDKDuXhY5rHCaDBvyAQrNh3XD6bYX8Ty", lamports: 91872000000, source: "5qXGXK96DDm8tYGcH1Er5RVLKLMtHxxsJWYKjuScD1Vp", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "Fzzx1oFf4X7b9Tws5Ldp5Tnc5u3dX3jzgQ58dp2bQXqb", mint: "FfiAdK89m762LxdCQTjdKB4qyH77PMzhgt2wbP5SGg6V", rentSysvar: "SysvarRent111111111111111111111111111111111", source: "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", systemProgram: "11111111111111111111111111111111", tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", wallet: "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", }, type: "create", }, program: "spl-associated-token-account", programId: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", }, { parsed: { info: { destination: "Fzzx1oFf4X7b9Tws5Ldp5Tnc5u3dX3jzgQ58dp2bQXqb", lamports: 2039280, source: "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "Fzzx1oFf4X7b9Tws5Ldp5Tnc5u3dX3jzgQ58dp2bQXqb", space: 165, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "Fzzx1oFf4X7b9Tws5Ldp5Tnc5u3dX3jzgQ58dp2bQXqb", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "Fzzx1oFf4X7b9Tws5Ldp5Tnc5u3dX3jzgQ58dp2bQXqb", mint: "FfiAdK89m762LxdCQTjdKB4qyH77PMzhgt2wbP5SGg6V", owner: "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { amount: "1", authority: "HS2eL9WJbh7pA4i4veK3YDwhGLRjY3uKryvG1NbHRprj", destination: "Fzzx1oFf4X7b9Tws5Ldp5Tnc5u3dX3jzgQ58dp2bQXqb", source: "3A5yUQ1taLvuyA2GaeF1Qjpcj5i6SK3cH4HTG6LmNKwt", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, { index: 3, instructions: [ { parsed: { info: { destination: "4bBkJxZtco4czavs94pEhpa3dTQfdvmDvYTxwHFH3ogx", lamports: 2234160, source: "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "4bBkJxZtco4czavs94pEhpa3dTQfdvmDvYTxwHFH3ogx", space: 193, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "4bBkJxZtco4czavs94pEhpa3dTQfdvmDvYTxwHFH3ogx", owner: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, ], }, ], logMessages: [ "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: PublicBuy", "Program log: Ok(252), Err(Custom(6013)), 252", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Transfer 897840 lamports to the new account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the account 7CJBzeZi6Zcben2iKLe7L1XrYfgNagk9hHdijtJpqsYe", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the account to the owning program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Completed assignation!", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 63218 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: PrintBidReceipt", "Program log: Transfer 2763120 lamports to the new account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the account GVnaCFMZtnX91PZtGQ8J6MxNQoKf8XyvLPtv4BYBykHX", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the account to the owning program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Completed assignation!", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 35456 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: ExecuteSale", "Program log: Ok(252), Err(Custom(6013)), 252", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [2]", "Program log: Transfer 2039280 lamports to the associated token account", "Program 11111111111111111111111111111111 invoke [3]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the associated token account", "Program 11111111111111111111111111111111 invoke [3]", "Program 11111111111111111111111111111111 success", "Program log: Assign the associated token account to the SPL Token program", "Program 11111111111111111111111111111111 invoke [3]", "Program 11111111111111111111111111111111 success", "Program log: Initialize the associated token account", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3297 of 103392 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 24372 of 123818 compute units", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2712 of 93057 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 112861 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: PrintPurchaseReceipt", "Program log: Transfer 2234160 lamports to the new account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the account 4bBkJxZtco4czavs94pEhpa3dTQfdvmDvYTxwHFH3ogx", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the account to the owning program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Completed assignation!", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 47454 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success", ], postBalances: [ 1041366112522, 43476452999, 2039280, 2234160, 0, 0, 0, 74091992398, 0, 0, 104685015440, 67120527091, 315028594814, 6905505600, 2533440, 2039280, 2763120, 225253532855, 1, 5616720, 898174080, 194991640, 1461600, 4085520, 1141440, 0, 152395037831, 0, 1009200, 953185920, ], postTokenBalances: [ { accountIndex: 2, mint: "FfiAdK89m762LxdCQTjdKB4qyH77PMzhgt2wbP5SGg6V", owner: "AYfUa1MUjjivuDKDuXhY5rHCaDBvyAQrNh3XD6bYX8Ty", uiTokenAmount: { amount: "0", decimals: 0, uiAmount: null, uiAmountString: "0", }, }, { accountIndex: 15, mint: "FfiAdK89m762LxdCQTjdKB4qyH77PMzhgt2wbP5SGg6V", owner: "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1, uiAmountString: "1", }, }, ], preBalances: [ 1140372256242, 40506452999, 2039280, 0, 0, 897840, 0, 73676192398, 0, 0, 103063395440, 66081027091, 223156594814, 6863925600, 2533440, 0, 0, 224214032855, 1, 5616720, 898174080, 194991640, 1461600, 4085520, 1141440, 0, 152395037831, 0, 1009200, 953185920, ], preTokenBalances: [ { accountIndex: 2, mint: "FfiAdK89m762LxdCQTjdKB4qyH77PMzhgt2wbP5SGg6V", owner: "AYfUa1MUjjivuDKDuXhY5rHCaDBvyAQrNh3XD6bYX8Ty", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 130271640, transaction: { message: { accountKeys: [ { pubkey: "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", signer: true, writable: true, }, { pubkey: "2e3dJ3mEjpdMDZsL5rGuCkMxqE116nBpMS2tKu9v8RRB", signer: false, writable: true, }, { pubkey: "3A5yUQ1taLvuyA2GaeF1Qjpcj5i6SK3cH4HTG6LmNKwt", signer: false, writable: true, }, { pubkey: "4bBkJxZtco4czavs94pEhpa3dTQfdvmDvYTxwHFH3ogx", signer: false, writable: true, }, { pubkey: "5qXGXK96DDm8tYGcH1Er5RVLKLMtHxxsJWYKjuScD1Vp", signer: false, writable: true, }, { pubkey: "7brnY48kvFyPQNcKPUdhAWsXGrijrynm3HMPgCETmPeP", signer: false, writable: true, }, { pubkey: "7CJBzeZi6Zcben2iKLe7L1XrYfgNagk9hHdijtJpqsYe", signer: false, writable: true, }, { pubkey: "7FzXBBPjzrNJbm9MrZKZcyvP3ojVeYPUG2XkBPVZvuBu", signer: false, writable: true, }, { pubkey: "836amfe6knfizUBxZqejArTUiY2FscQJjxGpCWwgw1vf", signer: false, writable: true, }, { pubkey: "91boRn3TZ7oeprHKk3q8QbyfevjZxLnL9LZsEqN468GE", signer: false, writable: true, }, { pubkey: "9BKWqDHfHZh9j39xakYVMdr6hXmCLHH5VfCpeq2idU9L", signer: false, writable: true, }, { pubkey: "9FYsKrNuEweb55Wa2jaj8wTKYDBvuCG3huhakEj96iN9", signer: false, writable: true, }, { pubkey: "AYfUa1MUjjivuDKDuXhY5rHCaDBvyAQrNh3XD6bYX8Ty", signer: false, writable: true, }, { pubkey: "DC2mkgwhy56w3viNtHDjJQmc7SGu2QX785bS4aexojwX", signer: false, writable: true, }, { pubkey: "DmqoaxU4ajeEoYbCTmuioTDDfBC8mdieBndAmS4s6KzQ", signer: false, writable: true, }, { pubkey: "Fzzx1oFf4X7b9Tws5Ldp5Tnc5u3dX3jzgQ58dp2bQXqb", signer: false, writable: true, }, { pubkey: "GVnaCFMZtnX91PZtGQ8J6MxNQoKf8XyvLPtv4BYBykHX", signer: false, writable: true, }, { pubkey: "HNGVuL5kqjDehw7KR63w9gxow32sX6xzRNgLb8GkbwCM", signer: false, writable: true, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "22CV2FHavBttAqfAZbxpcHzSXkL3TyDwqeykw6m22RDe", signer: false, writable: false, }, { pubkey: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", signer: false, writable: false, }, { pubkey: "BAfqGqULeJg6XVqw75orgNnmELcuwnTSnVpvhQmPPuFK", signer: false, writable: false, }, { pubkey: "FfiAdK89m762LxdCQTjdKB4qyH77PMzhgt2wbP5SGg6V", signer: false, writable: false, }, { pubkey: "GWErq8nJf5JQtohg5k7RTkiZmoCxvGBJqbMSfkrxYFFy", signer: false, writable: false, }, { pubkey: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", signer: false, writable: false, }, { pubkey: "HS2eL9WJbh7pA4i4veK3YDwhGLRjY3uKryvG1NbHRprj", signer: false, writable: false, }, { pubkey: "So11111111111111111111111111111111111111112", signer: false, writable: false, }, { pubkey: "Sysvar1nstructions1111111111111111111111111", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, ], instructions: [ { accounts: [ "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", "So11111111111111111111111111111111111111112", "3A5yUQ1taLvuyA2GaeF1Qjpcj5i6SK3cH4HTG6LmNKwt", "22CV2FHavBttAqfAZbxpcHzSXkL3TyDwqeykw6m22RDe", "5qXGXK96DDm8tYGcH1Er5RVLKLMtHxxsJWYKjuScD1Vp", "BAfqGqULeJg6XVqw75orgNnmELcuwnTSnVpvhQmPPuFK", "GWErq8nJf5JQtohg5k7RTkiZmoCxvGBJqbMSfkrxYFFy", "91boRn3TZ7oeprHKk3q8QbyfevjZxLnL9LZsEqN468GE", "7CJBzeZi6Zcben2iKLe7L1XrYfgNagk9hHdijtJpqsYe", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "SysvarRent111111111111111111111111111111111", ], data: "6BjfuCDKyc5ubRvGND8wVQzxSMF3fFbGgvtw", programId: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", }, { accounts: [ "GVnaCFMZtnX91PZtGQ8J6MxNQoKf8XyvLPtv4BYBykHX", "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", "11111111111111111111111111111111", "SysvarRent111111111111111111111111111111111", "Sysvar1nstructions1111111111111111111111111", ], data: "2D7j12dEPh7T3", programId: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", }, { accounts: [ "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", "AYfUa1MUjjivuDKDuXhY5rHCaDBvyAQrNh3XD6bYX8Ty", "3A5yUQ1taLvuyA2GaeF1Qjpcj5i6SK3cH4HTG6LmNKwt", "FfiAdK89m762LxdCQTjdKB4qyH77PMzhgt2wbP5SGg6V", "22CV2FHavBttAqfAZbxpcHzSXkL3TyDwqeykw6m22RDe", "So11111111111111111111111111111111111111112", "5qXGXK96DDm8tYGcH1Er5RVLKLMtHxxsJWYKjuScD1Vp", "AYfUa1MUjjivuDKDuXhY5rHCaDBvyAQrNh3XD6bYX8Ty", "Fzzx1oFf4X7b9Tws5Ldp5Tnc5u3dX3jzgQ58dp2bQXqb", "BAfqGqULeJg6XVqw75orgNnmELcuwnTSnVpvhQmPPuFK", "GWErq8nJf5JQtohg5k7RTkiZmoCxvGBJqbMSfkrxYFFy", "91boRn3TZ7oeprHKk3q8QbyfevjZxLnL9LZsEqN468GE", "2e3dJ3mEjpdMDZsL5rGuCkMxqE116nBpMS2tKu9v8RRB", "7CJBzeZi6Zcben2iKLe7L1XrYfgNagk9hHdijtJpqsYe", "7brnY48kvFyPQNcKPUdhAWsXGrijrynm3HMPgCETmPeP", "836amfe6knfizUBxZqejArTUiY2FscQJjxGpCWwgw1vf", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", "HS2eL9WJbh7pA4i4veK3YDwhGLRjY3uKryvG1NbHRprj", "SysvarRent111111111111111111111111111111111", "9BKWqDHfHZh9j39xakYVMdr6hXmCLHH5VfCpeq2idU9L", "9FYsKrNuEweb55Wa2jaj8wTKYDBvuCG3huhakEj96iN9", "HNGVuL5kqjDehw7KR63w9gxow32sX6xzRNgLb8GkbwCM", "7FzXBBPjzrNJbm9MrZKZcyvP3ojVeYPUG2XkBPVZvuBu", "DC2mkgwhy56w3viNtHDjJQmc7SGu2QX785bS4aexojwX", ], data: "63LNsZWnP5nH22Swj9EAzK3gbak4JGFuCCgGw", programId: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", }, { accounts: [ "4bBkJxZtco4czavs94pEhpa3dTQfdvmDvYTxwHFH3ogx", "DmqoaxU4ajeEoYbCTmuioTDDfBC8mdieBndAmS4s6KzQ", "GVnaCFMZtnX91PZtGQ8J6MxNQoKf8XyvLPtv4BYBykHX", "4ZGWPgjMNGHMrUJqyLFzEk92XDJwUFvyaAWbSm17ueHC", "11111111111111111111111111111111", "SysvarRent111111111111111111111111111111111", "Sysvar1nstructions1111111111111111111111111", ], data: "3u2uhbNXzTFBb", programId: "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk", }, ], recentBlockhash: "EqFgqBcEBZmzWeGyk9PuKAtwtD4ZEBxMmBdF3mqHryk8", }, signatures: [ "66EfiWJrPWzdu4BqFAff1Eov7JQfUrfMbmmxAKEx6QqrS2D6zm5XbsCP5yq3RnaUzUDxc5tWJBChBjmhWNFXzmaR", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/openSeaSaleTx.ts ================================================ import {ParsedConfirmedTransaction} from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { "blockTime": 1649206880, "meta": { "err": null, "fee": 10000, "innerInstructions": [{ "index": 0, "instructions": [{ "parsed": { "info": { "amount": "1", "delegate": "HS2eL9WJbh7pA4i4veK3YDwhGLRjY3uKryvG1NbHRprj", "owner": "J6CH2rnYqfhqk7fTKoPBpjYjMjzRYvtcWWYqXuTbX451", "source": "FWhvk9XkwbAYtBMyUQEzkKdF84ZHsRpxXabNKuX1WAWA" }, "type": "approve" }, "program": "spl-token", "programId": {"_bn": "06ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9"} }, { "parsed": { "info": { "destination": "AmsLrn1TU4VBj4kg9wNUaH12k63btEraUfXnnZJhdbwc", "lamports": 897840, "source": "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "account": "AmsLrn1TU4VBj4kg9wNUaH12k63btEraUfXnnZJhdbwc", "space": 1 }, "type": "allocate" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "account": "AmsLrn1TU4VBj4kg9wNUaH12k63btEraUfXnnZJhdbwc", "owner": "hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk" }, "type": "assign" }, "program": "system", "programId": {"_bn": "00"} }] }, { "index": 2, "instructions": [{ "parsed": { "info": { "destination": "71kwsvqZ5hTzQUB8piTRUBbCaoUWGMyN5Gb8vAtt9ZYV", "lamports": 1795680, "source": "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }] }, { "index": 5, "instructions": [{ "parsed": { "info": { "destination": "9BKWqDHfHZh9j39xakYVMdr6hXmCLHH5VfCpeq2idU9L", "lamports": 1539720000, "source": "BqdcmEKknjPMk2HNqG3ThiQQzeRLXarxY2PY9emsQ7v4" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "destination": "9FYsKrNuEweb55Wa2jaj8wTKYDBvuCG3huhakEj96iN9", "lamports": 987000000, "source": "BqdcmEKknjPMk2HNqG3ThiQQzeRLXarxY2PY9emsQ7v4" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "destination": "HNGVuL5kqjDehw7KR63w9gxow32sX6xzRNgLb8GkbwCM", "lamports": 987000000, "source": "BqdcmEKknjPMk2HNqG3ThiQQzeRLXarxY2PY9emsQ7v4" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "destination": "7FzXBBPjzrNJbm9MrZKZcyvP3ojVeYPUG2XkBPVZvuBu", "lamports": 394800000, "source": "BqdcmEKknjPMk2HNqG3ThiQQzeRLXarxY2PY9emsQ7v4" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "destination": "DC2mkgwhy56w3viNtHDjJQmc7SGu2QX785bS4aexojwX", "lamports": 39480000, "source": "BqdcmEKknjPMk2HNqG3ThiQQzeRLXarxY2PY9emsQ7v4" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "destination": "8mcjXbJ8j4VryYFNpcBCFS37Au8zVYU53WTVaruJWcKt", "lamports": 2350000000, "source": "BqdcmEKknjPMk2HNqG3ThiQQzeRLXarxY2PY9emsQ7v4" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "destination": "J6CH2rnYqfhqk7fTKoPBpjYjMjzRYvtcWWYqXuTbX451", "lamports": 87702000000, "source": "BqdcmEKknjPMk2HNqG3ThiQQzeRLXarxY2PY9emsQ7v4" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "amount": "1", "authority": "HS2eL9WJbh7pA4i4veK3YDwhGLRjY3uKryvG1NbHRprj", "destination": "FDQhqk3pQgSVj2praA5jD4pEKC9hzerSzGSXHeqAppAT", "source": "FWhvk9XkwbAYtBMyUQEzkKdF84ZHsRpxXabNKuX1WAWA" }, "type": "transfer" }, "program": "spl-token", "programId": {"_bn": "06ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9"} }] }], "logMessages": ["Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: Sell", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Approve", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2026 of 170370 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program log: Transfer 897840 lamports to the new account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the account AmsLrn1TU4VBj4kg9wNUaH12k63btEraUfXnnZJhdbwc", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the account to the owning program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Completed assignation!", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 55831 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success", "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: WithdrawFromFee", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 13348 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success", "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk invoke [1]", "Program log: Instruction: ExecuteSale", "Program log: Err(Custom(6013)), Ok(255), 255", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2712 of 128895 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk consumed 77023 of 200000 compute units", "Program hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk success"], "postBalances": [551806734363, 22295920, 2039280, 4085520, 101854902482, 0, 0, 224458141440, 2310000000, 2039280, 31502432899, 0, 944386067440, 823658107091, 82581107855, 31989638398, 4306995000, 5616720, 953185920, 1, 0, 1009200, 1461600, 152395037831, 898174080, 1141440], "postTokenBalances": [{ "accountIndex": 2, "mint": "CL8vqe2dL8Khh1fZtzSZL6DcXweSkdzGVS4t8LbmBh14", "owner": "J6CH2rnYqfhqk7fTKoPBpjYjMjzRYvtcWWYqXuTbX451", "uiTokenAmount": {"amount": "0", "decimals": 0, "uiAmount": null, "uiAmountString": "0"} }, { "accountIndex": 9, "mint": "CL8vqe2dL8Khh1fZtzSZL6DcXweSkdzGVS4t8LbmBh14", "owner": "EatSzWzfeo47TKCVQn6khv3qgWA9oKg28sfHcA4wsBZ1", "uiTokenAmount": {"amount": "1", "decimals": 0, "uiAmount": 1, "uiAmountString": "1"} }], "preBalances": [464104744363, 22295920, 2039280, 4085520, 101854902482, 0, 0, 224457243600, 96310000000, 2039280, 29152432899, 897840, 942846347440, 822671107091, 81594107855, 31594838398, 4267515000, 5616720, 953185920, 1, 0, 1009200, 1461600, 152395037831, 898174080, 1141440], "preTokenBalances": [{ "accountIndex": 2, "mint": "CL8vqe2dL8Khh1fZtzSZL6DcXweSkdzGVS4t8LbmBh14", "owner": "J6CH2rnYqfhqk7fTKoPBpjYjMjzRYvtcWWYqXuTbX451", "uiTokenAmount": {"amount": "1", "decimals": 0, "uiAmount": 1, "uiAmountString": "1"} }, { "accountIndex": 9, "mint": "CL8vqe2dL8Khh1fZtzSZL6DcXweSkdzGVS4t8LbmBh14", "owner": "EatSzWzfeo47TKCVQn6khv3qgWA9oKg28sfHcA4wsBZ1", "uiTokenAmount": {"amount": "0", "decimals": 0, "uiAmount": null, "uiAmountString": "0"} }], "rewards": [], "status": {"Ok": null} }, "slot": 128414021, "transaction": { "message": { "accountKeys": [{ "pubkey": {"_bn": "fdeb5502ecdd8477eabb88423bac3c1a819078ea4653259fb342f601cece8964"}, "signer": true, "writable": true }, { "pubkey": {"_bn": "5957cfc8a0e42253218140104fbeb444dec3d24b06d03de8efd6ea4d74b0f1b2"}, "signer": true, "writable": true }, { "pubkey": {"_bn": "d79fbc7eae510dfbb522862cc837eef953bc9b136af3fb4de03ed5b683f4eb27"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "2989d6a9ff6b2a168b81bed69f59efcb8172a8c663a80112cce020c86145700b"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "49c5e99524f07898034804274203258b3165710477bd5762d3d2d93ad0a4c3bf"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "9137a90629483d28899733c1bb90c0fd2beec2d5752a4aa6baee07acfd3cec67"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "554834cb47a18536de10856c40cd94b4d545e7e8ce23011bfe2af6b35ae3ad32"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "c9d644f2dbe938ba41f8253e0b77be77dff0061b92abebcaf6e6761906466c78"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "a10a268ecd21a1f027fd6b7cf53d3b3bfc9251fdb1cc8b3fb7fd0105fafa7b55"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "d331639817d825643f482d574803ced3236d199326b1c24b62df578c156be7e8"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "736fc48d12def6a316c4a28f340f33a6133c07a3044abb71fd07b52eac169a0b"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "3a8cda0ee1ac4b27c7c2c2f32b0da7743cf76968ad4dace0b5c7a044439dee09"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "79823cdb6ce50873db3f895e243f94d8220b9838702ef97bbaeb6970dd2394ff"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "7a97a8dd8992557bb1775608180d05c7f341865add90def08a1969f340016cd6"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "f32db6394ef748976b14ecfbc276dac42f08176162184b4bda980306206dd54a"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "5cfd4a8feec61e4228f0286c5d2b00510d2615263a20ed583f19da112744ed10"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "b51fa29b1ddbc2641f10f9d3c921395a89b34404b498a5e989d0c7a4e7b1f8c2"}, "signer": false, "writable": true }, { "pubkey": {"_bn": "4cebb96c7e001c56092f91df86d78c33272aca8fdfbf0cdceea319e36585a604"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "06ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "00"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "f4245e977593125fb15941b6c0a9260af4438bcd10355292a40b05df87f5d520"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "06a7d517192c5c51218cc94c3d4af17f58daee089ba1fd44e3dbd98a00000000"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "a8578e5a4636e8627d645731f173d52965942fcf79e0069678745ea1dce12673"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "069b8857feab8184fb687f634618c035dac439dc1aeb3b5598a0f00000000001"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "8c97258f4e2489f1bb3d1029148e0d830b5a1399daff1084048e7bd8dbe9f859"}, "signer": false, "writable": false }, { "pubkey": {"_bn": "0a6593863cba461564eae41373721546eb0151c9308276bbd4ad2a1c3a42107b"}, "signer": false, "writable": false }], "instructions": [{ "accounts": [{"_bn": "fdeb5502ecdd8477eabb88423bac3c1a819078ea4653259fb342f601cece8964"}, {"_bn": "d79fbc7eae510dfbb522862cc837eef953bc9b136af3fb4de03ed5b683f4eb27"}, {"_bn": "4cebb96c7e001c56092f91df86d78c33272aca8fdfbf0cdceea319e36585a604"}, {"_bn": "5957cfc8a0e42253218140104fbeb444dec3d24b06d03de8efd6ea4d74b0f1b2"}, {"_bn": "2989d6a9ff6b2a168b81bed69f59efcb8172a8c663a80112cce020c86145700b"}, {"_bn": "49c5e99524f07898034804274203258b3165710477bd5762d3d2d93ad0a4c3bf"}, {"_bn": "9137a90629483d28899733c1bb90c0fd2beec2d5752a4aa6baee07acfd3cec67"}, {"_bn": "554834cb47a18536de10856c40cd94b4d545e7e8ce23011bfe2af6b35ae3ad32"}, {"_bn": "06ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9"}, {"_bn": "00"}, {"_bn": "f4245e977593125fb15941b6c0a9260af4438bcd10355292a40b05df87f5d520"}, {"_bn": "06a7d517192c5c51218cc94c3d4af17f58daee089ba1fd44e3dbd98a00000000"}], "data": "81r6u24fHZhKcNPeduJymPQqvNmJErHCHUtrb", "programId": {"_bn": "0a6593863cba461564eae41373721546eb0151c9308276bbd4ad2a1c3a42107b"} }, { "parsed": { "info": { "destination": "5xyoD5hnWDBLsW6rjW2TBmqiDQsbod6Uaw15dRhNrDzn", "lamports": 897840, "source": "J6CH2rnYqfhqk7fTKoPBpjYjMjzRYvtcWWYqXuTbX451" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "accounts": [{"_bn": "5957cfc8a0e42253218140104fbeb444dec3d24b06d03de8efd6ea4d74b0f1b2"}, {"_bn": "5957cfc8a0e42253218140104fbeb444dec3d24b06d03de8efd6ea4d74b0f1b2"}, {"_bn": "49c5e99524f07898034804274203258b3165710477bd5762d3d2d93ad0a4c3bf"}, {"_bn": "2989d6a9ff6b2a168b81bed69f59efcb8172a8c663a80112cce020c86145700b"}, {"_bn": "00"}], "data": "PCrWfhudhPULPQhY2paGG7", "programId": {"_bn": "0a6593863cba461564eae41373721546eb0151c9308276bbd4ad2a1c3a42107b"} }, { "parsed": { "info": { "destination": "EatSzWzfeo47TKCVQn6khv3qgWA9oKg28sfHcA4wsBZ1", "lamports": 897840, "source": "71kwsvqZ5hTzQUB8piTRUBbCaoUWGMyN5Gb8vAtt9ZYV" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "parsed": { "info": { "destination": "J6CH2rnYqfhqk7fTKoPBpjYjMjzRYvtcWWYqXuTbX451", "lamports": 897840, "source": "71kwsvqZ5hTzQUB8piTRUBbCaoUWGMyN5Gb8vAtt9ZYV" }, "type": "transfer" }, "program": "system", "programId": {"_bn": "00"} }, { "accounts": [{"_bn": "c9d644f2dbe938ba41f8253e0b77be77dff0061b92abebcaf6e6761906466c78"}, {"_bn": "fdeb5502ecdd8477eabb88423bac3c1a819078ea4653259fb342f601cece8964"}, {"_bn": "d79fbc7eae510dfbb522862cc837eef953bc9b136af3fb4de03ed5b683f4eb27"}, {"_bn": "a8578e5a4636e8627d645731f173d52965942fcf79e0069678745ea1dce12673"}, {"_bn": "4cebb96c7e001c56092f91df86d78c33272aca8fdfbf0cdceea319e36585a604"}, {"_bn": "069b8857feab8184fb687f634618c035dac439dc1aeb3b5598a0f00000000001"}, {"_bn": "a10a268ecd21a1f027fd6b7cf53d3b3bfc9251fdb1cc8b3fb7fd0105fafa7b55"}, {"_bn": "fdeb5502ecdd8477eabb88423bac3c1a819078ea4653259fb342f601cece8964"}, {"_bn": "d331639817d825643f482d574803ced3236d199326b1c24b62df578c156be7e8"}, {"_bn": "5957cfc8a0e42253218140104fbeb444dec3d24b06d03de8efd6ea4d74b0f1b2"}, {"_bn": "2989d6a9ff6b2a168b81bed69f59efcb8172a8c663a80112cce020c86145700b"}, {"_bn": "49c5e99524f07898034804274203258b3165710477bd5762d3d2d93ad0a4c3bf"}, {"_bn": "736fc48d12def6a316c4a28f340f33a6133c07a3044abb71fd07b52eac169a0b"}, {"_bn": "3a8cda0ee1ac4b27c7c2c2f32b0da7743cf76968ad4dace0b5c7a044439dee09"}, {"_bn": "9137a90629483d28899733c1bb90c0fd2beec2d5752a4aa6baee07acfd3cec67"}, {"_bn": "554834cb47a18536de10856c40cd94b4d545e7e8ce23011bfe2af6b35ae3ad32"}, {"_bn": "06ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9"}, {"_bn": "00"}, {"_bn": "8c97258f4e2489f1bb3d1029148e0d830b5a1399daff1084048e7bd8dbe9f859"}, {"_bn": "f4245e977593125fb15941b6c0a9260af4438bcd10355292a40b05df87f5d520"}, {"_bn": "06a7d517192c5c51218cc94c3d4af17f58daee089ba1fd44e3dbd98a00000000"}, {"_bn": "79823cdb6ce50873db3f895e243f94d8220b9838702ef97bbaeb6970dd2394ff"}, {"_bn": "7a97a8dd8992557bb1775608180d05c7f341865add90def08a1969f340016cd6"}, {"_bn": "f32db6394ef748976b14ecfbc276dac42f08176162184b4bda980306206dd54a"}, {"_bn": "5cfd4a8feec61e4228f0286c5d2b00510d2615263a20ed583f19da112744ed10"}, {"_bn": "b51fa29b1ddbc2641f10f9d3c921395a89b34404b498a5e989d0c7a4e7b1f8c2"}], "data": "63LNsZWnP5nGqQbbaSU38R9yL1otajQKHuqEo", "programId": {"_bn": "0a6593863cba461564eae41373721546eb0151c9308276bbd4ad2a1c3a42107b"} }], "recentBlockhash": "D356DYrLMkLxzusPA8e9rYtZU99EE3mRJezP6yYiT5A2" }, "signatures": ["3uCUHGPcXJGA4c1fwwY2hn4pdfLYqUuqACqGHaWhPjCqt8YJrZ63QQrPqFn56qe3QEoL7BJtvQA8VuTCV4QPrEA2", "EQ3wAgjPo1BpZrF34g3faXQQkBscJZcwg7NRg3VS1bDWULsTJfToPzept7GJqHAm5pvAGoq2CaXMe9FZRabDQUD"] } } export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/solanartBidTx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const tx: ParsedConfirmedTransaction = { blockTime: 1641287764, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "2uMvHpeFfdc3wWKVPRPDAxBKdFpn6MQZXjmkxVGm9Uft", lamports: 2039280, source: "7A47s8jD3AfTEv1mvXXxETA5PmS7fhbwBWCzYm8r8wgC", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "2uMvHpeFfdc3wWKVPRPDAxBKdFpn6MQZXjmkxVGm9Uft", space: 165, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "2uMvHpeFfdc3wWKVPRPDAxBKdFpn6MQZXjmkxVGm9Uft", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "2uMvHpeFfdc3wWKVPRPDAxBKdFpn6MQZXjmkxVGm9Uft", mint: "Vz2HFKpKY3SDCJoUnpbnFs8mvCUvB2t83zXNZiTPRzN", owner: "7A47s8jD3AfTEv1mvXXxETA5PmS7fhbwBWCzYm8r8wgC", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, { index: 1, instructions: [ { parsed: { info: { destination: "65Xm7rcmR6pGS2oNLe4No4DDsWPQJV5aYtvprPgcvEM9", lamports: 2512560, source: "7A47s8jD3AfTEv1mvXXxETA5PmS7fhbwBWCzYm8r8wgC", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "65Xm7rcmR6pGS2oNLe4No4DDsWPQJV5aYtvprPgcvEM9", space: 233, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "65Xm7rcmR6pGS2oNLe4No4DDsWPQJV5aYtvprPgcvEM9", owner: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "65Xm7rcmR6pGS2oNLe4No4DDsWPQJV5aYtvprPgcvEM9", lamports: 12500000000, source: "7A47s8jD3AfTEv1mvXXxETA5PmS7fhbwBWCzYm8r8wgC", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, ], }, ], logMessages: [ "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]", "Program log: Transfer 2039280 lamports to the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the associated token account to the SPL Token program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Initialize the associated token account", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3449 of 177045 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 27053 of 200000 compute units", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz invoke [1]", "Program log: Instruction: CreateOffer", "Program log: Open bid at 12500000000 SOL", "Program log: Transfer 2512560 lamports to the new account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the account to the owning program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Completed assignation!", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz consumed 28388 of 200000 compute units", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz success", ], postBalances: [ 165731209, 2039280, 12502512560, 5616720, 1461600, 1, 1089991680, 1009200, 0, 898174080, 1141440, ], postTokenBalances: [ { accountIndex: 1, mint: "Vz2HFKpKY3SDCJoUnpbnFs8mvCUvB2t83zXNZiTPRzN", owner: "7A47s8jD3AfTEv1mvXXxETA5PmS7fhbwBWCzYm8r8wgC", uiTokenAmount: { amount: "0", decimals: 0, uiAmount: null, uiAmountString: "0", }, }, ], preBalances: [ 12670288049, 0, 0, 5616720, 1461600, 1, 1089991680, 1009200, 0, 898174080, 1141440, ], preTokenBalances: [], rewards: [], status: { Ok: null }, }, slot: 114743650, transaction: { message: { accountKeys: [ { pubkey: "7A47s8jD3AfTEv1mvXXxETA5PmS7fhbwBWCzYm8r8wgC", signer: true, writable: true, }, { pubkey: "2uMvHpeFfdc3wWKVPRPDAxBKdFpn6MQZXjmkxVGm9Uft", signer: false, writable: true, }, { pubkey: "65Xm7rcmR6pGS2oNLe4No4DDsWPQJV5aYtvprPgcvEM9", signer: false, writable: true, }, { pubkey: "FbViwEYEXdMM61mYm7JPrntaQdvMXqW1TCVLKkUCanRR", signer: false, writable: true, }, { pubkey: "Vz2HFKpKY3SDCJoUnpbnFs8mvCUvB2t83zXNZiTPRzN", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "AkZ8bE8AK3CQCVN8K2FNy1YSbBJV2MdU2JtTFVX2Z7uG", signer: false, writable: false, }, { pubkey: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", signer: false, writable: false, }, { pubkey: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", signer: false, writable: false, }, ], instructions: [ { parsed: { info: { account: "2uMvHpeFfdc3wWKVPRPDAxBKdFpn6MQZXjmkxVGm9Uft", mint: "Vz2HFKpKY3SDCJoUnpbnFs8mvCUvB2t83zXNZiTPRzN", rentSysvar: "SysvarRent111111111111111111111111111111111", source: "7A47s8jD3AfTEv1mvXXxETA5PmS7fhbwBWCzYm8r8wgC", systemProgram: "11111111111111111111111111111111", tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", wallet: "7A47s8jD3AfTEv1mvXXxETA5PmS7fhbwBWCzYm8r8wgC", }, type: "create", }, program: "spl-associated-token-account", programId: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", }, { accounts: [ "7A47s8jD3AfTEv1mvXXxETA5PmS7fhbwBWCzYm8r8wgC", "2uMvHpeFfdc3wWKVPRPDAxBKdFpn6MQZXjmkxVGm9Uft", "65Xm7rcmR6pGS2oNLe4No4DDsWPQJV5aYtvprPgcvEM9", "Vz2HFKpKY3SDCJoUnpbnFs8mvCUvB2t83zXNZiTPRzN", "FbViwEYEXdMM61mYm7JPrntaQdvMXqW1TCVLKkUCanRR", "11111111111111111111111111111111", "SysvarRent111111111111111111111111111111111", "AkZ8bE8AK3CQCVN8K2FNy1YSbBJV2MdU2JtTFVX2Z7uG", ], data: "119NsczBUo6o", programId: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", }, ], recentBlockhash: "U4c3bbizMbR7tmeEVh3k5nqcbdj5G79L8UrEsJyFY2G", }, signatures: [ "5ocxCdmdqHQd9Bp1ztaUsiSJMx2uAreYZc6N58B7GNeDTWr6s9bijzMEJN56hwHQhvWYQdZxWVw9abUMVweRCM2Y", ], }, }; export default tx; ================================================ FILE: src/lib/marketplaces/__fixtures__/solanartDelistingTx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const tx: ParsedConfirmedTransaction = { blockTime: 1641285168, meta: { err: null, fee: 10000, innerInstructions: [ { index: 2, instructions: [ { parsed: { info: { amount: "1", destination: "4otEhKcWzZGods7W8LPBeMuL82r9R4GcB6uznpVNayTu", multisigAuthority: "5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG", signers: ["5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG"], source: "2gT75AdRKbuR2GW8xX7b1sb4DYkhtweCC7SqrihQRJND", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { destination: "6ovfyEcNnYfQXX81bW1Donfoqd6xFwE2rvGk5zPmwH95", lamports: 1398960, source: "5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "6ovfyEcNnYfQXX81bW1Donfoqd6xFwE2rvGk5zPmwH95", space: 73, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "6ovfyEcNnYfQXX81bW1Donfoqd6xFwE2rvGk5zPmwH95", owner: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "4otEhKcWzZGods7W8LPBeMuL82r9R4GcB6uznpVNayTu", authorityType: "accountOwner", multisigAuthority: "5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG", newAuthority: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signers: ["5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG"], }, type: "setAuthority", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3446 of 200000 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz invoke [1]", "Program log: Instruction: Sell ", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3246 of 187951 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program log: Transfer 1398960 lamports to the new account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the account to the owning program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Completed assignation!", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: SetAuthority", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2153 of 167771 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz consumed 35270 of 200000 compute units", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz success", "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr invoke [1]", "Program log: Signed by 5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG", 'Program log: Memo (len 277): "{\\"name\\": \\"Ape Fam Passes\\", \\"desc\\": \\"undefined\\", \\"token_add\\": \\"6t22uGbB7gf4GFyy8hoM2HdVZ5JUmPPpYkMyQibEBNP3\\", \\"sale_add\\": \\"6ovfyEcNnYfQXX81bW1Donfoqd6xFwE2rvGk5zPmwH95\\", \\"img_url\\":\\"https://www.arweave.net/Ly7CFnIIdmJwcv_xCmSdIkPHn6rhd7vEdrxDfxP5xAE?ext=png\\", \\"price_sol\\":\\"0.08\\"}"', "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr consumed 112428 of 200000 compute units", "Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr success", ], postBalances: [ 379532048, 2039280, 4732222800372, 1398960, 2039280, 1461600, 1009200, 1, 1089991680, 0, 1141440, 521498880, ], postTokenBalances: [ { accountIndex: 1, mint: "6t22uGbB7gf4GFyy8hoM2HdVZ5JUmPPpYkMyQibEBNP3", owner: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, { accountIndex: 4, mint: "6t22uGbB7gf4GFyy8hoM2HdVZ5JUmPPpYkMyQibEBNP3", owner: "5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG", uiTokenAmount: { amount: "0", decimals: 0, uiAmount: null, uiAmountString: "0", }, }, ], preBalances: [ 382980288, 0, 4732222800372, 0, 2039280, 1461600, 1009200, 1, 1089991680, 0, 1141440, 521498880, ], preTokenBalances: [ { accountIndex: 4, mint: "6t22uGbB7gf4GFyy8hoM2HdVZ5JUmPPpYkMyQibEBNP3", owner: "5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 114739058, transaction: { message: { accountKeys: [ { pubkey: "5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG", signer: true, writable: true, }, { pubkey: "4otEhKcWzZGods7W8LPBeMuL82r9R4GcB6uznpVNayTu", signer: true, writable: true, }, { pubkey: "39fEpihLATXPJCQuSiXLUSiCbGchGYjeL39eyXh3KbyT", signer: false, writable: true, }, { pubkey: "6ovfyEcNnYfQXX81bW1Donfoqd6xFwE2rvGk5zPmwH95", signer: false, writable: true, }, { pubkey: "2gT75AdRKbuR2GW8xX7b1sb4DYkhtweCC7SqrihQRJND", signer: false, writable: true, }, { pubkey: "6t22uGbB7gf4GFyy8hoM2HdVZ5JUmPPpYkMyQibEBNP3", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "A45xw4fYgctZd5f7FAyxvTC4z7adBsBUHrDaZ1yDtyK3", signer: false, writable: false, }, { pubkey: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", signer: false, writable: false, }, { pubkey: "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", signer: false, writable: false, }, ], instructions: [ { parsed: { info: { lamports: 2039280, newAccount: "4otEhKcWzZGods7W8LPBeMuL82r9R4GcB6uznpVNayTu", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", source: "5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG", space: 165, }, type: "createAccount", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "4otEhKcWzZGods7W8LPBeMuL82r9R4GcB6uznpVNayTu", mint: "6t22uGbB7gf4GFyy8hoM2HdVZ5JUmPPpYkMyQibEBNP3", owner: "5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { accounts: [ "5sxGkw9fyyecvzX91PUTCStGCeaH5yeKNJwvQFk9BtdG", "39fEpihLATXPJCQuSiXLUSiCbGchGYjeL39eyXh3KbyT", "4otEhKcWzZGods7W8LPBeMuL82r9R4GcB6uznpVNayTu", "6ovfyEcNnYfQXX81bW1Donfoqd6xFwE2rvGk5zPmwH95", "6t22uGbB7gf4GFyy8hoM2HdVZ5JUmPPpYkMyQibEBNP3", "2gT75AdRKbuR2GW8xX7b1sb4DYkhtweCC7SqrihQRJND", "SysvarRent111111111111111111111111111111111", "11111111111111111111111111111111", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "A45xw4fYgctZd5f7FAyxvTC4z7adBsBUHrDaZ1yDtyK3", ], data: "3xPw7Me66Lco", programId: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", }, { parsed: '{"name": "Ape Fam Passes", "desc": "undefined", "token_add": "6t22uGbB7gf4GFyy8hoM2HdVZ5JUmPPpYkMyQibEBNP3", "sale_add": "6ovfyEcNnYfQXX81bW1Donfoqd6xFwE2rvGk5zPmwH95", "img_url":"https://www.arweave.net/Ly7CFnIIdmJwcv_xCmSdIkPHn6rhd7vEdrxDfxP5xAE?ext=png", "price_sol":"0.08"}', program: "spl-memo", programId: "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", }, ], recentBlockhash: "BUZJx6nDjaF6gsFc4k1Q3QStgGv7MNoLD2GL9RbvgzrS", }, signatures: [ "2vYBas6Pxb5d5khgBjhuEmQv39yLUC4vXCkYwafcRx6zKvbZJWky8k95AF6VopfNdqRUEyCTpMKsrHe2HUsNdRMx", "3yEZib2Q6mzg7EAvzz1dkdbiS4xMcXZogb36L7VuZb5P7CdjDDf7qZbq9cWhREhj1b3xdWYF8q8wxhWiDPQv8BQh", ], }, }; export default tx; ================================================ FILE: src/lib/marketplaces/__fixtures__/solanartListingTx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const tx: ParsedConfirmedTransaction = { blockTime: 1641289515, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "Fk1L2DxzWSfPWwYdcQey52h6SDDBcCfhaGGGkJEC8wpS", lamports: 2039280, source: "9v5rSYfUX86D8gK5vwt4YzEEdUYEBovF9yk5vbKSVxyL", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "Fk1L2DxzWSfPWwYdcQey52h6SDDBcCfhaGGGkJEC8wpS", space: 165, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "Fk1L2DxzWSfPWwYdcQey52h6SDDBcCfhaGGGkJEC8wpS", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "Fk1L2DxzWSfPWwYdcQey52h6SDDBcCfhaGGGkJEC8wpS", mint: "7eWhZsnVtArc174RezovPgLmV9FTYsz25XiAxfNqCtVw", owner: "9v5rSYfUX86D8gK5vwt4YzEEdUYEBovF9yk5vbKSVxyL", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, { index: 1, instructions: [ { parsed: { info: { amount: "1", destination: "Fk1L2DxzWSfPWwYdcQey52h6SDDBcCfhaGGGkJEC8wpS", multisigAuthority: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signers: ["3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK"], source: "CTHsUmcSy59PuT11nH8q5c6M8cr1M3pHqLsgGqLL5aAY", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { account: "CTHsUmcSy59PuT11nH8q5c6M8cr1M3pHqLsgGqLL5aAY", destination: "9v5rSYfUX86D8gK5vwt4YzEEdUYEBovF9yk5vbKSVxyL", multisigOwner: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signers: ["3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK"], }, type: "closeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]", "Program log: Transfer 2039280 lamports to the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the associated token account to the SPL Token program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Initialize the associated token account", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3449 of 179574 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 24524 of 200000 compute units", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz invoke [1]", "Program log: Instruction: Buy", "Program log: Sale cancelled by seller", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3246 of 91567 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: CloseAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2422 of 85370 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz consumed 118191 of 200000 compute units", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz success", ], postBalances: [ 228575215, 2039280, 0, 0, 4736967344972, 5616720, 0, 1461600, 1, 1089991680, 1009200, 11692287848, 1141440, 898174080, 1141440, ], postTokenBalances: [ { accountIndex: 1, mint: "7eWhZsnVtArc174RezovPgLmV9FTYsz25XiAxfNqCtVw", owner: "9v5rSYfUX86D8gK5vwt4YzEEdUYEBovF9yk5vbKSVxyL", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], preBalances: [ 227181255, 0, 2039280, 1398960, 4736967344972, 5616720, 0, 1461600, 1, 1089991680, 1009200, 11692287848, 1141440, 898174080, 1141440, ], preTokenBalances: [ { accountIndex: 2, mint: "7eWhZsnVtArc174RezovPgLmV9FTYsz25XiAxfNqCtVw", owner: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 114746790, transaction: { message: { accountKeys: [ { pubkey: "9v5rSYfUX86D8gK5vwt4YzEEdUYEBovF9yk5vbKSVxyL", signer: true, writable: true, }, { pubkey: "Fk1L2DxzWSfPWwYdcQey52h6SDDBcCfhaGGGkJEC8wpS", signer: false, writable: true, }, { pubkey: "CTHsUmcSy59PuT11nH8q5c6M8cr1M3pHqLsgGqLL5aAY", signer: false, writable: true, }, { pubkey: "Aun1LnrvccfXBY51RzV7MgKzCBjTcHWBMZ1Bpg9j22BP", signer: false, writable: true, }, { pubkey: "39fEpihLATXPJCQuSiXLUSiCbGchGYjeL39eyXh3KbyT", signer: false, writable: true, }, { pubkey: "3zkXT9JQMdB4zNMisF4ftR3uf5gFuETx57U8k5BimLWm", signer: false, writable: true, }, { pubkey: "3dQav8NYwBh6g34UQU6KHEN7VkGBXgbMJMPRF81wbBD7", signer: false, writable: true, }, { pubkey: "7eWhZsnVtArc174RezovPgLmV9FTYsz25XiAxfNqCtVw", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signer: false, writable: false, }, { pubkey: "7gDpaG9kUXHTz1dj4eVfykqtXnKq2efyuGigdMeCy74B", signer: false, writable: false, }, { pubkey: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", signer: false, writable: false, }, { pubkey: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", signer: false, writable: false, }, ], instructions: [ { parsed: { info: { account: "Fk1L2DxzWSfPWwYdcQey52h6SDDBcCfhaGGGkJEC8wpS", mint: "7eWhZsnVtArc174RezovPgLmV9FTYsz25XiAxfNqCtVw", rentSysvar: "SysvarRent111111111111111111111111111111111", source: "9v5rSYfUX86D8gK5vwt4YzEEdUYEBovF9yk5vbKSVxyL", systemProgram: "11111111111111111111111111111111", tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", wallet: "9v5rSYfUX86D8gK5vwt4YzEEdUYEBovF9yk5vbKSVxyL", }, type: "create", }, program: "spl-associated-token-account", programId: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", }, { accounts: [ "9v5rSYfUX86D8gK5vwt4YzEEdUYEBovF9yk5vbKSVxyL", "Fk1L2DxzWSfPWwYdcQey52h6SDDBcCfhaGGGkJEC8wpS", "CTHsUmcSy59PuT11nH8q5c6M8cr1M3pHqLsgGqLL5aAY", "9v5rSYfUX86D8gK5vwt4YzEEdUYEBovF9yk5vbKSVxyL", "Aun1LnrvccfXBY51RzV7MgKzCBjTcHWBMZ1Bpg9j22BP", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "39fEpihLATXPJCQuSiXLUSiCbGchGYjeL39eyXh3KbyT", "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", "3zkXT9JQMdB4zNMisF4ftR3uf5gFuETx57U8k5BimLWm", "3dQav8NYwBh6g34UQU6KHEN7VkGBXgbMJMPRF81wbBD7", "7gDpaG9kUXHTz1dj4eVfykqtXnKq2efyuGigdMeCy74B", "11111111111111111111111111111111", ], data: "4h6bzpF8MKT5", programId: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", }, ], recentBlockhash: "4F19LcyPH1jyhtNmTcmjanUNWbZ6mfcs3p6duigudnvc", }, signatures: [ "5cCMhRF6ppWZQhybWmaNP94hKFe25rUwz7oUyNscA9Bm7feoJDkr2oJZ4VKJ5V6jCXCuKvVQKNjJfF1Tyo8nFpRc", ], }, }; export default tx; ================================================ FILE: src/lib/marketplaces/__fixtures__/solanartSaleFromBidTx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1639780263, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { amount: "1", destination: "GVmmfuw9Hz4o8Nu5a2SwmqR2cmy56BregpsajPbaoTT", multisigAuthority: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signers: ["3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK"], source: "kgAeqE79wDesZ5B1eRzj8yoXcYuCXZQyCv65izPt9Ko", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { account: "kgAeqE79wDesZ5B1eRzj8yoXcYuCXZQyCv65izPt9Ko", destination: "4Zn5nPcXCyWwFGuMLUw5zPfN1b1o1bsXE2cz8zEPBW5J", multisigOwner: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signers: ["3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK"], }, type: "closeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, { index: 1, instructions: [ { parsed: { info: { amount: "1", destination: "BrLQpUw6UQM4rsUxCvU93virPJNVoza51ZGvyjBXVGsd", multisigAuthority: "4Zn5nPcXCyWwFGuMLUw5zPfN1b1o1bsXE2cz8zEPBW5J", signers: ["4Zn5nPcXCyWwFGuMLUw5zPfN1b1o1bsXE2cz8zEPBW5J"], source: "GVmmfuw9Hz4o8Nu5a2SwmqR2cmy56BregpsajPbaoTT", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz invoke [1]", "Program log: Instruction: Buy", "Program log: Sale cancelled by seller", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3246 of 121132 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: CloseAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2422 of 114924 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz consumed 88759 of 200000 compute units", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz invoke [1]", "Program log: Instruction: Accept Offer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3246 of 159788 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program log: NFT sold for 4 SOL", "Program log: Closing the PDA info account...", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz consumed 90016 of 200000 compute units", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz success", ], postBalances: [ 4336722874, 2039280, 0, 0, 2123892480067, 5616720, 0, 5159570, 140404422499, 0, 50985256238, 2039280, 1089991680, 11368141155, 1141440, 1, 1461600, 1141440, ], postTokenBalances: [ { accountIndex: 1, mint: "HRGYe4hDNjNVCjmwhmnEiiZtbjzShCwazC1JEyERXRUo", owner: "4Zn5nPcXCyWwFGuMLUw5zPfN1b1o1bsXE2cz8zEPBW5J", uiTokenAmount: { amount: "0", decimals: 0, uiAmount: null, uiAmountString: "0", }, }, { accountIndex: 11, mint: "HRGYe4hDNjNVCjmwhmnEiiZtbjzShCwazC1JEyERXRUo", owner: "6bPDVYs5Ewutp8jqurwqfWkL3UeUAGouZg5RJxNY2yAM", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], preBalances: [ 193289635, 2039280, 2039280, 1398960, 2123757480067, 5616720, 0, 5159570, 140179422499, 4502512560, 50982743677, 2039280, 1089991680, 11368141155, 1141440, 1, 1461600, 1141440, ], preTokenBalances: [ { accountIndex: 1, mint: "HRGYe4hDNjNVCjmwhmnEiiZtbjzShCwazC1JEyERXRUo", owner: "4Zn5nPcXCyWwFGuMLUw5zPfN1b1o1bsXE2cz8zEPBW5J", uiTokenAmount: { amount: "0", decimals: 0, uiAmount: null, uiAmountString: "0", }, }, { accountIndex: 2, mint: "HRGYe4hDNjNVCjmwhmnEiiZtbjzShCwazC1JEyERXRUo", owner: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, { accountIndex: 11, mint: "HRGYe4hDNjNVCjmwhmnEiiZtbjzShCwazC1JEyERXRUo", owner: "6bPDVYs5Ewutp8jqurwqfWkL3UeUAGouZg5RJxNY2yAM", uiTokenAmount: { amount: "0", decimals: 0, uiAmount: null, uiAmountString: "0", }, }, ], rewards: [], status: { Ok: null }, }, slot: 112028221, transaction: { message: { accountKeys: [ { pubkey: "4Zn5nPcXCyWwFGuMLUw5zPfN1b1o1bsXE2cz8zEPBW5J", signer: true, writable: true, }, { pubkey: "GVmmfuw9Hz4o8Nu5a2SwmqR2cmy56BregpsajPbaoTT", signer: false, writable: true, }, { pubkey: "kgAeqE79wDesZ5B1eRzj8yoXcYuCXZQyCv65izPt9Ko", signer: false, writable: true, }, { pubkey: "4D9oH4cf7JLbkw3SwS6FEQsLji6cPJWjPip4X4eM1YNh", signer: false, writable: true, }, { pubkey: "39fEpihLATXPJCQuSiXLUSiCbGchGYjeL39eyXh3KbyT", signer: false, writable: true, }, { pubkey: "9zd7ep4EcvXJYVG6QEM1Bx9Rgo9tVUjBUy3wK6Ba9GqF", signer: false, writable: true, }, { pubkey: "1hkDGEFnMFVwSjsjsLchwBqFLfu3jaGMZiJ4Ve74H2j", signer: false, writable: true, }, { pubkey: "9nicnEJ1pfssv3CWxQFMebFBrs5Cqun8WEmwwLqapLeX", signer: false, writable: true, }, { pubkey: "7BPrveGEsNmr5UU2bSzSmHh8wbhB1NWTw4dXqykqpm1e", signer: false, writable: true, }, { pubkey: "2y78y9m3hg5b62PnHVguzMCk6w3brP3DLii1bG577wKy", signer: false, writable: true, }, { pubkey: "6bPDVYs5Ewutp8jqurwqfWkL3UeUAGouZg5RJxNY2yAM", signer: false, writable: true, }, { pubkey: "BrLQpUw6UQM4rsUxCvU93virPJNVoza51ZGvyjBXVGsd", signer: false, writable: true, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signer: false, writable: false, }, { pubkey: "7gDpaG9kUXHTz1dj4eVfykqtXnKq2efyuGigdMeCy74B", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "HRGYe4hDNjNVCjmwhmnEiiZtbjzShCwazC1JEyERXRUo", signer: false, writable: false, }, { pubkey: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", signer: false, writable: false, }, ], instructions: [ { accounts: [ "4Zn5nPcXCyWwFGuMLUw5zPfN1b1o1bsXE2cz8zEPBW5J", "GVmmfuw9Hz4o8Nu5a2SwmqR2cmy56BregpsajPbaoTT", "kgAeqE79wDesZ5B1eRzj8yoXcYuCXZQyCv65izPt9Ko", "4Zn5nPcXCyWwFGuMLUw5zPfN1b1o1bsXE2cz8zEPBW5J", "4D9oH4cf7JLbkw3SwS6FEQsLji6cPJWjPip4X4eM1YNh", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "39fEpihLATXPJCQuSiXLUSiCbGchGYjeL39eyXh3KbyT", "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", "9zd7ep4EcvXJYVG6QEM1Bx9Rgo9tVUjBUy3wK6Ba9GqF", "1hkDGEFnMFVwSjsjsLchwBqFLfu3jaGMZiJ4Ve74H2j", "7gDpaG9kUXHTz1dj4eVfykqtXnKq2efyuGigdMeCy74B", "11111111111111111111111111111111", "9nicnEJ1pfssv3CWxQFMebFBrs5Cqun8WEmwwLqapLeX", "7BPrveGEsNmr5UU2bSzSmHh8wbhB1NWTw4dXqykqpm1e", ], data: "4hBxPUj432du", programId: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", }, { accounts: [ "4Zn5nPcXCyWwFGuMLUw5zPfN1b1o1bsXE2cz8zEPBW5J", "2y78y9m3hg5b62PnHVguzMCk6w3brP3DLii1bG577wKy", "6bPDVYs5Ewutp8jqurwqfWkL3UeUAGouZg5RJxNY2yAM", "HRGYe4hDNjNVCjmwhmnEiiZtbjzShCwazC1JEyERXRUo", "GVmmfuw9Hz4o8Nu5a2SwmqR2cmy56BregpsajPbaoTT", "BrLQpUw6UQM4rsUxCvU93virPJNVoza51ZGvyjBXVGsd", "39fEpihLATXPJCQuSiXLUSiCbGchGYjeL39eyXh3KbyT", "11111111111111111111111111111111", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "9zd7ep4EcvXJYVG6QEM1Bx9Rgo9tVUjBUy3wK6Ba9GqF", "1hkDGEFnMFVwSjsjsLchwBqFLfu3jaGMZiJ4Ve74H2j", "7gDpaG9kUXHTz1dj4eVfykqtXnKq2efyuGigdMeCy74B", "9nicnEJ1pfssv3CWxQFMebFBrs5Cqun8WEmwwLqapLeX", "7BPrveGEsNmr5UU2bSzSmHh8wbhB1NWTw4dXqykqpm1e", ], data: "2UjPnnnBE3Af", programId: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", }, ], recentBlockhash: "Em4WDQzwUFkTapWSkLS1vZ7D2xQDHH2WT7X8sFHDKfQq", }, signatures: [ "4PJ7X1ZCEj68n2HXfVx48jGnqgu9rWAxquVihpNvDizbZ5V5vUHViz2N54HHMUiBvKtx7mbmYAQ4unURg9YEgLM6", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/solanartSaleTx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1635558562, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "9zdSFMpnjS9J6DrM82HjxxwGVVU37VfBiZ5fJA796Lf8", lamports: 2039280, source: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "9zdSFMpnjS9J6DrM82HjxxwGVVU37VfBiZ5fJA796Lf8", space: 165, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "9zdSFMpnjS9J6DrM82HjxxwGVVU37VfBiZ5fJA796Lf8", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "9zdSFMpnjS9J6DrM82HjxxwGVVU37VfBiZ5fJA796Lf8", mint: "2se1H9trBxHVTeiCpuk4manbaq1b4iio2MYWcLCnLMFa", owner: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, { index: 1, instructions: [ { parsed: { info: { destination: "8Kag8CqNdCX55s4A5W4iraS71h6mv6uTHqsJbexdrrZm", lamports: 640250000, source: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "aury7LJUae7a92PBo35vVbP61GX8VbyxFKausvUtBrt", lamports: 344750000, source: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "E6dkaYhqbZN3a1pDrdbajJ9D8xA66LBBcjWi6dDNAuJH", lamports: 591000000, source: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "H9Yi8cfwvwKJvpLMPTLftPdVkvmzkN7BamcAT5hyEh8j", lamports: 18124000000, source: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { amount: "1", destination: "9zdSFMpnjS9J6DrM82HjxxwGVVU37VfBiZ5fJA796Lf8", multisigAuthority: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signers: ["3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK"], source: "Cf4R5CaFyNxoCBcgHfRRz9ghCqTHkVK6TZZeEkoPiC7h", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { account: "Cf4R5CaFyNxoCBcgHfRRz9ghCqTHkVK6TZZeEkoPiC7h", destination: "H9Yi8cfwvwKJvpLMPTLftPdVkvmzkN7BamcAT5hyEh8j", multisigOwner: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signers: ["3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK"], }, type: "closeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]", "Program log: Transfer 2039280 lamports to the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the associated token account to the SPL Token program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Initialize the associated token account", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3449 of 177045 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 27053 of 200000 compute units", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz invoke [1]", "Program log: Instruction: Buy", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3246 of 105675 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: CloseAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2422 of 99467 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz consumed 104312 of 200000 compute units", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz success", ], postBalances: [ 68758795402, 2039280, 0, 23457503023, 0, 13298071422340, 5616720, 0, 4572720, 2908453635467, 11341016825250, 1461600, 1, 1089991680, 1, 11352771574, 1141440, 898174080, 1141440, ], postTokenBalances: [ { accountIndex: 1, mint: "2se1H9trBxHVTeiCpuk4manbaq1b4iio2MYWcLCnLMFa", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], preBalances: [ 88460839682, 0, 2039280, 5330064783, 1398960, 13297480422340, 5616720, 0, 4572720, 2907813385467, 11340672075250, 1461600, 1, 1089991680, 1, 11352771574, 1141440, 898174080, 1141440, ], preTokenBalances: [ { accountIndex: 2, mint: "2se1H9trBxHVTeiCpuk4manbaq1b4iio2MYWcLCnLMFa", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 104223648, transaction: { message: { accountKeys: [ { pubkey: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", signer: true, writable: true, }, { pubkey: "9zdSFMpnjS9J6DrM82HjxxwGVVU37VfBiZ5fJA796Lf8", signer: false, writable: true, }, { pubkey: "Cf4R5CaFyNxoCBcgHfRRz9ghCqTHkVK6TZZeEkoPiC7h", signer: false, writable: true, }, { pubkey: "H9Yi8cfwvwKJvpLMPTLftPdVkvmzkN7BamcAT5hyEh8j", signer: false, writable: true, }, { pubkey: "BwjN9d3PkX9pWEEeF2vMmGKrPG1DKxVQwcXSrDGW2vsq", signer: false, writable: true, }, { pubkey: "E6dkaYhqbZN3a1pDrdbajJ9D8xA66LBBcjWi6dDNAuJH", signer: false, writable: true, }, { pubkey: "3ZRNaauaSBp3L1kRsnTkWy2S174NL6DMgZ7xhsNYyExQ", signer: false, writable: true, }, { pubkey: "8xVXixWBmbP5QQMMNseHqs12qrJxjNoEUjUsntRnYxq4", signer: false, writable: true, }, { pubkey: "9vwYtcJsH1MskNaixcjgNBnvBDkTBhyg25umod1rgMQL", signer: false, writable: true, }, { pubkey: "8Kag8CqNdCX55s4A5W4iraS71h6mv6uTHqsJbexdrrZm", signer: false, writable: true, }, { pubkey: "aury7LJUae7a92PBo35vVbP61GX8VbyxFKausvUtBrt", signer: false, writable: true, }, { pubkey: "2se1H9trBxHVTeiCpuk4manbaq1b4iio2MYWcLCnLMFa", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signer: false, writable: false, }, { pubkey: "7gDpaG9kUXHTz1dj4eVfykqtXnKq2efyuGigdMeCy74B", signer: false, writable: false, }, { pubkey: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", signer: false, writable: false, }, { pubkey: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", signer: false, writable: false, }, ], instructions: [ { parsed: { info: { account: "9zdSFMpnjS9J6DrM82HjxxwGVVU37VfBiZ5fJA796Lf8", mint: "2se1H9trBxHVTeiCpuk4manbaq1b4iio2MYWcLCnLMFa", rentSysvar: "SysvarRent111111111111111111111111111111111", source: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", systemProgram: "11111111111111111111111111111111", tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", wallet: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", }, type: "create", }, program: "spl-associated-token-account", programId: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", }, { accounts: [ "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", "9zdSFMpnjS9J6DrM82HjxxwGVVU37VfBiZ5fJA796Lf8", "Cf4R5CaFyNxoCBcgHfRRz9ghCqTHkVK6TZZeEkoPiC7h", "H9Yi8cfwvwKJvpLMPTLftPdVkvmzkN7BamcAT5hyEh8j", "BwjN9d3PkX9pWEEeF2vMmGKrPG1DKxVQwcXSrDGW2vsq", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "E6dkaYhqbZN3a1pDrdbajJ9D8xA66LBBcjWi6dDNAuJH", "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", "3ZRNaauaSBp3L1kRsnTkWy2S174NL6DMgZ7xhsNYyExQ", "8xVXixWBmbP5QQMMNseHqs12qrJxjNoEUjUsntRnYxq4", "7gDpaG9kUXHTz1dj4eVfykqtXnKq2efyuGigdMeCy74B", "11111111111111111111111111111111", "9vwYtcJsH1MskNaixcjgNBnvBDkTBhyg25umod1rgMQL", "8Kag8CqNdCX55s4A5W4iraS71h6mv6uTHqsJbexdrrZm", "aury7LJUae7a92PBo35vVbP61GX8VbyxFKausvUtBrt", ], data: "4h81nn1umFAX", programId: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", }, ], recentBlockhash: "TWVEwBmUbkK2gfYh51WtWJWU8goct1c7duTmQBeDwFy", }, signatures: [ "3qmi5w4ZJsf1PJED21bNVpwgobcMFxUeb6coKJNA32F1fW5WELDXAxnjLzsfnxGnKQfKLuwVBk3xD6zbcjvA9GTX", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/__fixtures__/solanartSalesTxWithFloatingLamport.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const sale: ParsedConfirmedTransaction = { blockTime: 1636283774, meta: { err: null, fee: 5000, innerInstructions: [ { index: 0, instructions: [ { parsed: { info: { destination: "9tF3mCaEws8NTDzkgAzyzAs5k9QirWyx86XojD36dsZ7", lamports: 2039280, source: "5pYfvPkuzasUXFFVTFNf28XcAfxvUGvYxbaxgRib1Wp5", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "9tF3mCaEws8NTDzkgAzyzAs5k9QirWyx86XojD36dsZ7", space: 165, }, type: "allocate", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "9tF3mCaEws8NTDzkgAzyzAs5k9QirWyx86XojD36dsZ7", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, type: "assign", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "9tF3mCaEws8NTDzkgAzyzAs5k9QirWyx86XojD36dsZ7", mint: "2sAwuzSPbD4DtR1Gz1m8YutrbDY7EBoSoYKJr1ZsKrCQ", owner: "5pYfvPkuzasUXFFVTFNf28XcAfxvUGvYxbaxgRib1Wp5", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, { index: 1, instructions: [ { parsed: { info: { destination: "3dDRiW6oCZKYTLDuvqon4cc6RjKP7ujziFvVRGRML7hU", lamports: 3000000, source: "5pYfvPkuzasUXFFVTFNf28XcAfxvUGvYxbaxgRib1Wp5", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "E6dkaYhqbZN3a1pDrdbajJ9D8xA66LBBcjWi6dDNAuJH", lamports: 1800000, source: "5pYfvPkuzasUXFFVTFNf28XcAfxvUGvYxbaxgRib1Wp5", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "5vx26hiGCfmF5bv7QV7i4A811ugRaSdcxmWXBSXY5ZTC", lamports: 55199999, source: "5pYfvPkuzasUXFFVTFNf28XcAfxvUGvYxbaxgRib1Wp5", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { amount: "1", destination: "9tF3mCaEws8NTDzkgAzyzAs5k9QirWyx86XojD36dsZ7", multisigAuthority: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signers: ["3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK"], source: "8hukBnVGijxP7F643ruv7rcWEJsJPMvgL53bmcAGiPAH", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { parsed: { info: { account: "8hukBnVGijxP7F643ruv7rcWEJsJPMvgL53bmcAGiPAH", destination: "5vx26hiGCfmF5bv7QV7i4A811ugRaSdcxmWXBSXY5ZTC", multisigOwner: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signers: ["3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK"], }, type: "closeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]", "Program log: Transfer 2039280 lamports to the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Allocate space for the associated token account", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Assign the associated token account to the SPL Token program", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Initialize the associated token account", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3449 of 177045 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 27053 of 200000 compute units", "Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz invoke [1]", "Program log: Instruction: Buy", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3246 of 107571 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: CloseAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2422 of 101363 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz consumed 102352 of 200000 compute units", "Program CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz success", ], postBalances: [ 325817008, 2039280, 0, 4430959642, 0, 15164085127515, 5616720, 0, 4572720, 12754572570, 1461600, 1, 1089991680, 1009200, 11358560469, 1141440, 898174080, 1141440, ], postTokenBalances: [ { accountIndex: 1, mint: "2sAwuzSPbD4DtR1Gz1m8YutrbDY7EBoSoYKJr1ZsKrCQ", owner: "5pYfvPkuzasUXFFVTFNf28XcAfxvUGvYxbaxgRib1Wp5", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], preBalances: [ 387861287, 0, 2039280, 4372321403, 1398960, 15164083327515, 5616720, 0, 4572720, 12751572570, 1461600, 1, 1089991680, 1009200, 11358560469, 1141440, 898174080, 1141440, ], preTokenBalances: [ { accountIndex: 2, mint: "2sAwuzSPbD4DtR1Gz1m8YutrbDY7EBoSoYKJr1ZsKrCQ", owner: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 105671633, transaction: { message: { accountKeys: [ { pubkey: "5pYfvPkuzasUXFFVTFNf28XcAfxvUGvYxbaxgRib1Wp5", signer: true, writable: true, }, { pubkey: "9tF3mCaEws8NTDzkgAzyzAs5k9QirWyx86XojD36dsZ7", signer: false, writable: true, }, { pubkey: "8hukBnVGijxP7F643ruv7rcWEJsJPMvgL53bmcAGiPAH", signer: false, writable: true, }, { pubkey: "5vx26hiGCfmF5bv7QV7i4A811ugRaSdcxmWXBSXY5ZTC", signer: false, writable: true, }, { pubkey: "GQBVvcYkuWoiwBAZW1X1ZX8kB7R3XVK8j3bSfSkBykKb", signer: false, writable: true, }, { pubkey: "E6dkaYhqbZN3a1pDrdbajJ9D8xA66LBBcjWi6dDNAuJH", signer: false, writable: true, }, { pubkey: "sG8RwqMUcvTddsYk4yaTgX4c5BV36u9U47MGL1vawJi", signer: false, writable: true, }, { pubkey: "DFgnW3SPcegjLqnzPnN37xgStX7CDADyKjVyRejLFqWX", signer: false, writable: true, }, { pubkey: "5uaCGB5mA3ARmLS1KpAKVnYq9nyDAgZkTJwPKTPsa2pZ", signer: false, writable: true, }, { pubkey: "3dDRiW6oCZKYTLDuvqon4cc6RjKP7ujziFvVRGRML7hU", signer: false, writable: true, }, { pubkey: "2sAwuzSPbD4DtR1Gz1m8YutrbDY7EBoSoYKJr1ZsKrCQ", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", signer: false, writable: false, }, { pubkey: "7gDpaG9kUXHTz1dj4eVfykqtXnKq2efyuGigdMeCy74B", signer: false, writable: false, }, { pubkey: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", signer: false, writable: false, }, { pubkey: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", signer: false, writable: false, }, ], instructions: [ { parsed: { info: { account: "9tF3mCaEws8NTDzkgAzyzAs5k9QirWyx86XojD36dsZ7", mint: "2sAwuzSPbD4DtR1Gz1m8YutrbDY7EBoSoYKJr1ZsKrCQ", rentSysvar: "SysvarRent111111111111111111111111111111111", source: "5pYfvPkuzasUXFFVTFNf28XcAfxvUGvYxbaxgRib1Wp5", systemProgram: "11111111111111111111111111111111", tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", wallet: "5pYfvPkuzasUXFFVTFNf28XcAfxvUGvYxbaxgRib1Wp5", }, type: "create", }, program: "spl-associated-token-account", programId: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", }, { accounts: [ "5pYfvPkuzasUXFFVTFNf28XcAfxvUGvYxbaxgRib1Wp5", "9tF3mCaEws8NTDzkgAzyzAs5k9QirWyx86XojD36dsZ7", "8hukBnVGijxP7F643ruv7rcWEJsJPMvgL53bmcAGiPAH", "5vx26hiGCfmF5bv7QV7i4A811ugRaSdcxmWXBSXY5ZTC", "GQBVvcYkuWoiwBAZW1X1ZX8kB7R3XVK8j3bSfSkBykKb", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "E6dkaYhqbZN3a1pDrdbajJ9D8xA66LBBcjWi6dDNAuJH", "3D49QorJyNaL4rcpiynbuS3pRH4Y7EXEM6v6ZGaqfFGK", "sG8RwqMUcvTddsYk4yaTgX4c5BV36u9U47MGL1vawJi", "DFgnW3SPcegjLqnzPnN37xgStX7CDADyKjVyRejLFqWX", "7gDpaG9kUXHTz1dj4eVfykqtXnKq2efyuGigdMeCy74B", "11111111111111111111111111111111", "5uaCGB5mA3ARmLS1KpAKVnYq9nyDAgZkTJwPKTPsa2pZ", "3dDRiW6oCZKYTLDuvqon4cc6RjKP7ujziFvVRGRML7hU", ], data: "4hBjytn4rqCB", programId: "CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz", }, ], recentBlockhash: "6LYk9fauGNQ4pDbZ2vSxB8pSoc5ZRJPvRsisxuPdoW2G", }, signatures: [ "5YHfVoe9jSBTa3FWcYV11i6MNtPALTpot1ca6PydLx4nGNyCPc7cghwbz6VXgAyMrxUZDkkp2QoYfot74ckLsUYG", ], }, }; export default sale; ================================================ FILE: src/lib/marketplaces/__fixtures__/solseaSaleTx.ts ================================================ import { ParsedConfirmedTransaction } from "@solana/web3.js"; const saleTx: ParsedConfirmedTransaction = { blockTime: 1638570298, meta: { err: null, fee: 10000, innerInstructions: [ { index: 2, instructions: [ { parsed: { info: { destination: "6T4f5bdrd9ffTtehqAj9BGyxahysRGcaUZeDzA1XN52N", lamports: 90000000, source: "pKqUqVxK3i3MB9qNSYPtwGFpT2H3CbsneGM5H9zLhT3", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "6cSjZRcDEjpRxHmqXGjJXzqCEs7cHgxiWseA9gzCeQp9", lamports: 0, source: "pKqUqVxK3i3MB9qNSYPtwGFpT2H3CbsneGM5H9zLhT3", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "AmgaigwTiBwXsXJ28LnQuhDH9xtEBueDVC5fEpwjthXZ", lamports: 291000000, source: "pKqUqVxK3i3MB9qNSYPtwGFpT2H3CbsneGM5H9zLhT3", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { destination: "G1F5nSzq6CNDMz8bBMadfGp2qTC7hU9dETS33KReQsR2", lamports: 2619000000, source: "pKqUqVxK3i3MB9qNSYPtwGFpT2H3CbsneGM5H9zLhT3", }, type: "transfer", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { amount: "1", authority: "3yfoLAcet3gBg5gHKCmmjVq8Dgn5hoUdrRf5TKa8RoKS", destination: "6pdd4CSFfRhqS9PvLQf81FdxxyEA4r2mfKxvad3bTx5V", source: "BX6VddKUNXs9RGC5gFkSnBWDhTNPrXUsAJo4PBq2z9Qp", }, type: "transfer", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, ], }, ], logMessages: [ "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]", "Program log: Instruction: InitializeAccount", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3446 of 200000 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program 617jbWo616ggkDxvW1Le8pV38XLbVSyWY8ae6QUmGBAU invoke [1]", "Program log: entry", "Program log: Transfering tokens!", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: price = 3000000000", "Program log: seller_fee = 1000", "Program log: total fee = 291000000", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program 11111111111111111111111111111111 invoke [2]", "Program 11111111111111111111111111111111 success", "Program log: Transfering NFT!", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", "Program log: Instruction: Transfer", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3121 of 177902 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", "Program 617jbWo616ggkDxvW1Le8pV38XLbVSyWY8ae6QUmGBAU consumed 27529 of 200000 compute units", "Program 617jbWo616ggkDxvW1Le8pV38XLbVSyWY8ae6QUmGBAU success", ], postBalances: [ 21683053765, 2039280, 2027313, 0, 2667750167, 3023688478796, 2039280, 4572720, 59263089529, 1461600, 1009200, 1089991680, 1, 1141440, ], postTokenBalances: [ { accountIndex: 1, mint: "8gaYezSKFxJu4Q7F7xLWTbFBLAEsKefqq9i8stML7B6S", owner: "pKqUqVxK3i3MB9qNSYPtwGFpT2H3CbsneGM5H9zLhT3", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, { accountIndex: 6, mint: "8gaYezSKFxJu4Q7F7xLWTbFBLAEsKefqq9i8stML7B6S", owner: "3yfoLAcet3gBg5gHKCmmjVq8Dgn5hoUdrRf5TKa8RoKS", uiTokenAmount: { amount: "0", decimals: 0, uiAmount: null, uiAmountString: "0", }, }, ], preBalances: [ 24685103045, 0, 2027313, 0, 48750167, 3023598478796, 2039280, 4572720, 58972089529, 1461600, 1009200, 1089991680, 1, 1141440, ], preTokenBalances: [ { accountIndex: 6, mint: "8gaYezSKFxJu4Q7F7xLWTbFBLAEsKefqq9i8stML7B6S", owner: "3yfoLAcet3gBg5gHKCmmjVq8Dgn5hoUdrRf5TKa8RoKS", uiTokenAmount: { amount: "1", decimals: 0, uiAmount: 1.0, uiAmountString: "1", }, }, ], rewards: [], status: { Ok: null }, }, slot: 109928435, transaction: { message: { accountKeys: [ { pubkey: "pKqUqVxK3i3MB9qNSYPtwGFpT2H3CbsneGM5H9zLhT3", signer: true, writable: true, }, { pubkey: "6pdd4CSFfRhqS9PvLQf81FdxxyEA4r2mfKxvad3bTx5V", signer: true, writable: true, }, { pubkey: "GdPyDFpdmwrF6FUTzjbYXqqmKsYMUfKZriX6C6DSWn1M", signer: false, writable: true, }, { pubkey: "3yfoLAcet3gBg5gHKCmmjVq8Dgn5hoUdrRf5TKa8RoKS", signer: false, writable: true, }, { pubkey: "G1F5nSzq6CNDMz8bBMadfGp2qTC7hU9dETS33KReQsR2", signer: false, writable: true, }, { pubkey: "6T4f5bdrd9ffTtehqAj9BGyxahysRGcaUZeDzA1XN52N", signer: false, writable: true, }, { pubkey: "BX6VddKUNXs9RGC5gFkSnBWDhTNPrXUsAJo4PBq2z9Qp", signer: false, writable: true, }, { pubkey: "6cSjZRcDEjpRxHmqXGjJXzqCEs7cHgxiWseA9gzCeQp9", signer: false, writable: true, }, { pubkey: "AmgaigwTiBwXsXJ28LnQuhDH9xtEBueDVC5fEpwjthXZ", signer: false, writable: true, }, { pubkey: "8gaYezSKFxJu4Q7F7xLWTbFBLAEsKefqq9i8stML7B6S", signer: false, writable: false, }, { pubkey: "SysvarRent111111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", signer: false, writable: false, }, { pubkey: "11111111111111111111111111111111", signer: false, writable: false, }, { pubkey: "617jbWo616ggkDxvW1Le8pV38XLbVSyWY8ae6QUmGBAU", signer: false, writable: false, }, ], instructions: [ { parsed: { info: { lamports: 2039280, newAccount: "6pdd4CSFfRhqS9PvLQf81FdxxyEA4r2mfKxvad3bTx5V", owner: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", source: "pKqUqVxK3i3MB9qNSYPtwGFpT2H3CbsneGM5H9zLhT3", space: 165, }, type: "createAccount", }, program: "system", programId: "11111111111111111111111111111111", }, { parsed: { info: { account: "6pdd4CSFfRhqS9PvLQf81FdxxyEA4r2mfKxvad3bTx5V", mint: "8gaYezSKFxJu4Q7F7xLWTbFBLAEsKefqq9i8stML7B6S", owner: "pKqUqVxK3i3MB9qNSYPtwGFpT2H3CbsneGM5H9zLhT3", rentSysvar: "SysvarRent111111111111111111111111111111111", }, type: "initializeAccount", }, program: "spl-token", programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", }, { accounts: [ "GdPyDFpdmwrF6FUTzjbYXqqmKsYMUfKZriX6C6DSWn1M", "3yfoLAcet3gBg5gHKCmmjVq8Dgn5hoUdrRf5TKa8RoKS", "pKqUqVxK3i3MB9qNSYPtwGFpT2H3CbsneGM5H9zLhT3", "3yfoLAcet3gBg5gHKCmmjVq8Dgn5hoUdrRf5TKa8RoKS", "pKqUqVxK3i3MB9qNSYPtwGFpT2H3CbsneGM5H9zLhT3", "G1F5nSzq6CNDMz8bBMadfGp2qTC7hU9dETS33KReQsR2", "6pdd4CSFfRhqS9PvLQf81FdxxyEA4r2mfKxvad3bTx5V", "6T4f5bdrd9ffTtehqAj9BGyxahysRGcaUZeDzA1XN52N", "BX6VddKUNXs9RGC5gFkSnBWDhTNPrXUsAJo4PBq2z9Qp", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "6cSjZRcDEjpRxHmqXGjJXzqCEs7cHgxiWseA9gzCeQp9", "AmgaigwTiBwXsXJ28LnQuhDH9xtEBueDVC5fEpwjthXZ", ], data: "EE", programId: "617jbWo616ggkDxvW1Le8pV38XLbVSyWY8ae6QUmGBAU", }, ], recentBlockhash: "6381s6mpNEK9iwq62XQJWiS6p1y5wch74JVEyHAJAF28", }, signatures: [ "4XuN4e8nDz6jpCB6YXEBP7i3EFaoN9hVGkxMRTJeuu2i9dMZ7rJKCwU9A5zN8DoPw9dm5zbVrJwSfw5xctyJ82GU", "3PPUTxkidJYcnV1Roj784C9rY2StTRXYFUGDQYfh6APF81fbye1vaumQ368cdPpdrWDAbucNWTtDN1588KYQFmDc", ], }, }; export default saleTx; ================================================ FILE: src/lib/marketplaces/alphaArt.test.ts ================================================ import alphaArt from "./alphaArt"; import alphaArtSaleTx from "./__fixtures__/alphaArtSaleTx"; import { Connection } from "@solana/web3.js"; jest.mock("lib/solana/NFTData", () => { return { fetchNFTData: () => { return {}; }, }; }); describe("alphaArt", () => { afterEach(() => { jest.clearAllMocks(); }); const conn = new Connection("https://test/"); test("itemUrl", () => { expect(alphaArt.itemURL("xxx1")).toEqual("https://alpha.art/t/xxx1"); }); describe("parseNFTSale", () => { test("sale transaction should return NFTSale", async () => { const sale = await alphaArt.parseNFTSale(conn, alphaArtSaleTx); expect(sale.transaction).toEqual( "4CwUFDv1JoaK4iN2chARePZZjAPrXdcX2VwDC2Snt4gNgdmFfqtiUR6HkniFNfLwh35rQzTjqhpDkgzWw69e6Svc" ); expect(sale.token).toEqual( "14Cc7DA6MwpNdAZZYdLxK6WQ9meMaeLX1WsCyLRf5nqw" ); expect(sale.soldAt).toEqual(new Date(1636257741 * 1000)); expect(sale.marketplace).toEqual(alphaArt); expect(sale.getPriceInLamport()).toEqual(780000000); expect(sale.getPriceInSOL()).toEqual(0.78); expect(sale.buyer).toEqual( "CScUB4iBTfCWaFkj5gRpXx42HVpAgDvPJgbQxtETRXi1" ); }); test("non-sale transaction should return null", async () => { const invalidSaleTx = { ...alphaArtSaleTx, meta: { ...alphaArtSaleTx.meta, preTokenBalances: [], postTokenBalances: [], }, }; expect(await alphaArt.parseNFTSale(conn, invalidSaleTx)).toBe(null); }); test("non Alpha art transaction", async () => { const nonAlphaArtSaleTx = { ...alphaArtSaleTx, }; nonAlphaArtSaleTx.meta.logMessages = ["Program xxx invoke [1]"]; expect(await alphaArt.parseNFTSale(conn, nonAlphaArtSaleTx)).toBe(null); }); }); }); ================================================ FILE: src/lib/marketplaces/alphaArt.ts ================================================ import { Marketplace, NFTSale } from "./types"; import { parseNFTSaleOnTx } from "./helper"; const alphaArt: Marketplace = { name: "Alpha art", iconURL: "https://alpha.art/favicon.ico", programId: ["HZaWndaNWHFDd9Dhk5pqUUtsmoBCqzb1MLu3NAh1VX6B"], itemURL: (token: String) => `https://alpha.art/t/${token}`, profileURL: (address: String) => `https://explorer.solana.com/address/${address}`, parseNFTSale(web3Conn, txResp): Promise { return parseNFTSaleOnTx(web3Conn, txResp, this, 1); }, }; export default alphaArt; ================================================ FILE: src/lib/marketplaces/digitalEyes.test.ts ================================================ import digitalEyes from "./digitalEyes"; import digitalEyesSaleTx from "./__fixtures__/digitalEyesSaleTx"; import { Connection } from "@solana/web3.js"; jest.mock("lib/solana/NFTData", () => { return { fetchNFTData: () => { return {}; }, }; }); describe("digitalEyes", () => { const conn = new Connection("https://test/"); test("itemUrl", () => { expect(digitalEyes.itemURL("xxx1")).toEqual( "https://digitaleyes.market/item/xxx1" ); }); describe("parseNFTSale", () => { test("sale transaction should return NFTSale", async () => { const sale = await digitalEyes.parseNFTSale(conn, digitalEyesSaleTx); expect(sale.transaction).toEqual( "5DqZaNrvEKLLUupRTbt56eYG4f8U25uxYH4wCw5UevbEttkBLDJuF9927yacw7J74kTtWKC1xuyA1QBQRakh3cd1" ); expect(sale.token).toEqual( "ECoNeXqLJofE7WZZzkntyTr3kqgrELmcLiY4HN9qb2ae" ); expect(sale.soldAt).toEqual(new Date(1635551628 * 1000)); expect(sale.marketplace).toEqual(digitalEyes); expect(sale.getPriceInLamport()).toEqual(30000000); expect(sale.getPriceInSOL()).toEqual(0.03); const expectedTransfers = [ { to: "3iYf9hHQPciwgJ1TCjpRUp1A3QW4AfaK7J6vCmETRMuu", from: "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", revenue: { amount: 750000, symbol: "lamport" }, }, { to: "6EjCH2MQBucbfCXZbrUpP3jTkYLJi3r87rdyptrrNAXJ", from: "59uZhxZov3UeBG3QQWg8rKLm4MHGA89V3XLBRUxbqXaV", revenue: { amount: 29250000, symbol: "lamport" }, }, ]; expect(sale.transfers.length).toEqual(expectedTransfers.length); expectedTransfers.forEach((expectedTransfer, index) => { const transfer = sale.transfers[index]; expect(transfer.from).toEqual(expectedTransfer.from); expect(transfer.to).toEqual(expectedTransfer.to); expect(transfer.revenue).toEqual(expectedTransfer.revenue); }); }); test("non-sale transaction should return null", async () => { const invalidSaleTx = { ...digitalEyesSaleTx, meta: { ...digitalEyesSaleTx.meta, preTokenBalances: [], postTokenBalances: [], }, }; expect(await digitalEyes.parseNFTSale(conn, invalidSaleTx)).toBe(null); }); test("non Solanart transaction", async () => { const invalidSaleTx = { ...digitalEyesSaleTx, }; invalidSaleTx.meta.logMessages = ["Program xxx invoke [1]"]; expect(await digitalEyes.parseNFTSale(conn, invalidSaleTx)).toBe(null); }); }); }); ================================================ FILE: src/lib/marketplaces/digitalEyes.ts ================================================ import { Marketplace, NFTSale } from "./types"; import { parseNFTSaleOnTx } from "./helper"; const digitalEyes: Marketplace = { name: "Digital Eyes", programId: ["A7p8451ktDCHq5yYaHczeLMYsjRsAkzc3hCXcSrwYHU7"], iconURL: "https://digitaleyes.market/apple-touch-icon.png", itemURL: (token: String) => `https://digitaleyes.market/item/${token}`, profileURL: (address: String) => `https://explorer.solana.com/address/${address}`, parseNFTSale(web3Conn, txResp): Promise { return parseNFTSaleOnTx(web3Conn, txResp, this, 1); }, }; export default digitalEyes; ================================================ FILE: src/lib/marketplaces/exchangeArt.test.ts ================================================ import exchangeArt from "./exchangeArt"; import exchangeArtSaleTx from "./__fixtures__/exchangeArtSaleTx"; import exchangeArtSaleTxV2 from "./__fixtures__/exchangeArtSaleTxV2"; import { Connection } from "@solana/web3.js"; jest.mock("lib/solana/NFTData", () => { return { fetchNFTData: () => { return {}; }, }; }); describe("exchangeArt", () => { afterEach(() => { jest.clearAllMocks(); }); const conn = new Connection("https://test/"); test("itemUrl", () => { expect(exchangeArt.itemURL("xxx1")).toEqual( "https://exchange.art/single/xxx1" ); }); describe("parseNFTSale", () => { test("sale transaction should return NFTSale", async () => { const sale = await exchangeArt.parseNFTSale(conn, exchangeArtSaleTx); expect(sale.transaction).toEqual( "4WniSeFvZHsnZEDueeWhP18dUC9bGwZjoQ19RQq14796GCdb7WVRsTjK8AZCLLhL136p4J96minzfZcKVjY3fNAY" ); expect(sale.token).toEqual( "GSG2UXwfv5EE1Ad62bCc3pWcgJy5NRdFYof9JyyFZDMS" ); expect(sale.soldAt).toEqual(new Date(1636465965 * 1000)); expect(sale.marketplace).toEqual(exchangeArt); expect(sale.getPriceInLamport()).toEqual(1990000000); expect(sale.getPriceInSOL()).toEqual(1.99); expect(sale.buyer).toEqual( "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ" ); const expectedTransfers = [ { to: "6482e33zrerYfhKAjPR2ncMSrH2tbTy5LDjdhB5PXzxd", revenue: { amount: 49750000, symbol: "lamport" }, from: "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ", }, { to: "4QJzmvKWpneEgHDa99QCb4hWtAhxA6qfFNtYWAb8Cw93", revenue: { amount: 99500000, symbol: "lamport" }, from: "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ", }, { to: "7ZvteCjTjt5HxYbmxyzo9xMavDEXkNLUG6r6pJJXijvj", revenue: { amount: 99500000, symbol: "lamport" }, from: "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ", }, { to: "7A6AV8pMznyt9eBXGbnkcgbuKhStz3vDQvWcRBoYWV5R", revenue: { amount: 1741250000, symbol: "lamport" }, from: "8WX1T8ofK91YxcPHp9t1wnQanHfcu4Nzy3fwQqMNGecJ", }, ]; expect(sale.transfers.length).toEqual(expectedTransfers.length); expectedTransfers.forEach((expectedTransfer, index) => { const transfer = sale.transfers[index]; expect(transfer.from).toEqual(expectedTransfer.from); expect(transfer.to).toEqual(expectedTransfer.to); expect(transfer.revenue).toEqual(expectedTransfer.revenue); }); }); test("sale transaction v2 should return NFTSale", async () => { const sale = await exchangeArt.parseNFTSale(conn, exchangeArtSaleTxV2); expect(sale.marketplace).toEqual(exchangeArt); expect(sale.getPriceInLamport()).toEqual(200000000); expect(sale.getPriceInSOL()).toEqual(0.2); expect(sale.buyer).toEqual( "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3" ); const expectedTransfers = [ { to: "6482e33zrerYfhKAjPR2ncMSrH2tbTy5LDjdhB5PXzxd", revenue: { amount: 5000000, symbol: "lamport" }, from: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", }, { to: "8pJyixptCqPPLSkT9qqjMmJjAELdP8YiGsL1ihNmSsaE", revenue: { amount: 100000000, symbol: "lamport" }, from: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", }, { to: "3Z6T94rMaTKjfdQb9ShunvMJ6C9LqDqEkfKBBeGArpzp", revenue: { amount: 95000000, symbol: "lamport" }, from: "FR4xWcvhxA2dLTDda5cmD1zUxz9gnzrVhhLq4owcAzt3", }, ]; expect(sale.transfers.length).toEqual(expectedTransfers.length); expectedTransfers.forEach((expectedTransfer, index) => { const transfer = sale.transfers[index]; expect(transfer.from).toEqual(expectedTransfer.from); expect(transfer.to).toEqual(expectedTransfer.to); expect(transfer.revenue).toEqual(expectedTransfer.revenue); }); }); test("non-sale transaction should return null", async () => { const invalidSaleTx = { ...exchangeArtSaleTx, meta: { ...exchangeArtSaleTx.meta, preTokenBalances: [], postTokenBalances: [], }, }; expect(await exchangeArt.parseNFTSale(conn, invalidSaleTx)).toBe(null); }); test("non exchange art transaction", async () => { const invalidSaleTx = { ...exchangeArtSaleTx, }; invalidSaleTx.meta.logMessages = ["Program xxx invoke [1]"]; expect(await exchangeArt.parseNFTSale(conn, invalidSaleTx)).toBe(null); }); }); }); ================================================ FILE: src/lib/marketplaces/exchangeArt.ts ================================================ import { Marketplace, NFTSale } from "./types"; import { parseNFTSaleOnTx } from "./helper"; const exchangeArt: Marketplace = { name: "Exchange Art", programId: ["AmK5g2XcyptVLCFESBCJqoSfwV3znGoVYQnqEnaAZKWn"], iconURL: "https://cdn.exchange.art/static/apple-meta-logo.png", itemURL: (token: String) => `https://exchange.art/single/${token}`, profileURL: (address: String) => `https://explorer.solana.com/address/${address}`, parseNFTSale(web3Conn, txResp): Promise { return parseNFTSaleOnTx(web3Conn, txResp, this); }, }; export default exchangeArt; ================================================ FILE: src/lib/marketplaces/helper.test.ts ================================================ import { parseNFTSaleOnTx } from "./helper"; import solanartSalesTxWithFloatingLamport from "./__fixtures__/solanartSalesTxWithFloatingLamport"; import solanart from "./solanart"; import magicEdenSaleTx from "./__fixtures__/magicEdenSaleTx"; import digitalEyeSaleTx from "./__fixtures__/digitalEyesSaleTx"; import solanartSaleTx from "./__fixtures__/solanartSaleTx"; import alphaArtSaleTx from "./__fixtures__/alphaArtSaleTx"; import exchangeArtSaleTx from "./__fixtures__/exchangeArtSaleTx"; import exchangeArtSaleTxV2 from "./__fixtures__/exchangeArtSaleTxV2"; import solseaSaleTx from "./__fixtures__/solseaSaleTx"; import magicEden from "./magicEden"; import digitalEyes from "./digitalEyes"; import alphaArt from "./alphaArt"; import exchangeArt from "./exchangeArt"; import solsea from "./solsea"; import { Connection } from "@solana/web3.js"; import magicEdenFailedTx from "./__fixtures__/magicEdenFailedTx"; jest.mock("lib/solana/NFTData", () => { return { fetchNFTData: () => { return {}; }, }; }); describe("helper", () => { afterEach(() => { jest.clearAllMocks(); }); const conn = new Connection("https://test/"); describe("parseNFTSaleOnTx", () => { test("getPriceInLamport", async () => { const nftSale = await parseNFTSaleOnTx( conn, solanartSalesTxWithFloatingLamport, solanart, 1 ); expect(nftSale).toBeTruthy(); expect(nftSale.getPriceInSOL()).toEqual(0.06); }); test("should parse nft sales", async () => { const sale = await parseNFTSaleOnTx(conn, magicEdenSaleTx, magicEden); expect(sale.transaction).toEqual( "626EgwuS6dbUKrkZujQCFjHiRsz92ALR5gNAEg2eMpZzEo88Cci6HifpDFcvgYR8j88nXUq1nRUA7UDRdvB7Y6WD" ); expect(sale.token).toEqual( "8pwYVy61QiSTJGPc8yYfkVPLBBr8r17WkpUFRhNK6cjK" ); expect(sale.soldAt).toEqual(new Date(1635141315000)); expect(sale.marketplace).toEqual(magicEden); expect(sale.getPriceInLamport()).toEqual(3720000000); expect(sale.getPriceInSOL()).toEqual(3.72); expect(sale.seller).toEqual( "HihC794BdNCetkizxdFjVD2KiKWirGYbm2ojvRYXQd6H" ); const expectedTransfers = [ { to: "2NZukH2TXpcuZP4htiuT8CFxcaQSWzkkR6kepSWnZ24Q", from: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", revenue: { amount: 74400000, symbol: "lamport", }, }, { to: "4eQwMqAA4c2VUD51rqfAke7kqeFLAxcxSB67rtFjDyZA", from: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", revenue: { amount: 74400000, symbol: "lamport", }, }, { to: "Dz9kwoBVVzF11cHeKotQpA7t4aeCQsgRpVw4dg8zkntg", from: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", revenue: { amount: 74400000, symbol: "lamport", }, }, { to: "4xHEEswq2T2E5uNoa1uw34RNKzPerayBHxX3P4SaR7cD", from: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", revenue: { amount: 74400000, symbol: "lamport", }, }, { to: "33CJriD17bUScYW7eKFjM6BPfkFWPerHfdpvtw3a8JdN", from: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", revenue: { amount: 74400000, symbol: "lamport", }, }, { to: "HWZybKNqMa93EmHK2ESL2v1XShcnt4ma4nFf14497jNS", from: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", revenue: { amount: 74400000, symbol: "lamport", }, }, { to: "HihC794BdNCetkizxdFjVD2KiKWirGYbm2ojvRYXQd6H", from: "U7ZkJtaAwvBHt9Tw5BK8sdp2wLrEe7p1g3kFxB9WJCu", revenue: { amount: 3273600000, symbol: "lamport", }, }, ]; expect(sale.transfers.length).toEqual(expectedTransfers.length); expectedTransfers.forEach((expectedTransfer, index) => { const transfer = sale.transfers[index]; expect(transfer.from).toEqual(expectedTransfer.from); expect(transfer.to).toEqual(expectedTransfer.to); expect(transfer.revenue).toEqual(expectedTransfer.revenue); }); }); test("should parse all marketplace purchases", async () => { const invalidTx = { ...magicEdenSaleTx, meta: { ...magicEdenSaleTx.meta, preTokenBalances: [], postTokenBalances: [], }, }; const tests = [ { tx: magicEdenSaleTx, martketplace: magicEden, shouldParsed: true }, { tx: invalidTx, martketplace: magicEden, shouldParsed: false }, { tx: magicEdenSaleTx, martketplace: digitalEyes, shouldParsed: false }, { tx: digitalEyeSaleTx, martketplace: digitalEyes, shouldParsed: true }, { tx: digitalEyeSaleTx, martketplace: solanart, shouldParsed: false }, { tx: solanartSaleTx, martketplace: solanart, shouldParsed: true }, { tx: solanartSaleTx, martketplace: digitalEyes, shouldParsed: false }, { tx: alphaArtSaleTx, martketplace: alphaArt, shouldParsed: true }, { tx: solseaSaleTx, martketplace: solsea, shouldParsed: true }, { tx: magicEdenFailedTx, martketplace: magicEden, shouldParsed: false }, { tx: exchangeArtSaleTx, martketplace: exchangeArt, shouldParsed: true, }, { tx: exchangeArtSaleTxV2, martketplace: exchangeArt, shouldParsed: true, }, ].map(async (testCase) => { const nftSale = await parseNFTSaleOnTx( conn, testCase.tx, testCase.martketplace ); expect(Boolean(nftSale)).toEqual(testCase.shouldParsed); }); return Promise.all(tests); }); }); }); ================================================ FILE: src/lib/marketplaces/helper.ts ================================================ import { Connection, ParsedConfirmedTransaction, ParsedConfirmedTransactionMeta, ParsedInnerInstruction, ParsedInstruction, ParsedMessageAccount, TokenBalance, } from "@solana/web3.js"; import { Marketplace, NFTSale, SaleMethod, Transfer } from "./types"; import { LamportPerSOL } from "../solana"; import { fetchNFTData } from "../solana/NFTData"; import solanart from "./solanart"; export function getTransfersFromInnerInstructions( innerInstructions: any ): Transfer[] { if (!innerInstructions) { return []; } const instructions = innerInstructions.instructions as ParsedInstruction[]; if (!instructions[0]?.parsed) { return []; } return instructions .filter((i: any) => { return Boolean(i?.parsed?.info.lamports) && i.parsed.type === "transfer"; }) .map((i: any) => { const { info } = i.parsed; return { from: info.source, to: info.destination, revenue: { amount: info.lamports, symbol: "lamport", }, }; }); } function txContainsLog( tx: ParsedConfirmedTransaction, values: string[] ): boolean { if (!tx.meta?.logMessages) { return false; } return Boolean( tx.meta.logMessages.find((msg) => { return Boolean(values.find((value) => msg.includes(value))); }) ); } function getTokenOriginFromTx( tx: ParsedConfirmedTransaction ): string | undefined { if (!tx.meta?.preTokenBalances?.length) { return; } let balance = tx.meta?.preTokenBalances.find((balance) => { if (!balance.uiTokenAmount.uiAmount) { return false; } return balance.uiTokenAmount.uiAmount > 0; }); if (balance) { return (balance as TokenBalance & { owner?: string }).owner; } return; } function wasTokenMovedInTx(tx: ParsedConfirmedTransaction): boolean { if (!tx.meta?.postTokenBalances?.length) { return false; } if (!tx.meta?.preTokenBalances?.length) { return false; } let originalBalance = tx.meta?.preTokenBalances.find((balance) => { if (!balance.uiTokenAmount.uiAmount) { return false; } return balance.uiTokenAmount.uiAmount > 0; }); const balanceWithToken = tx.meta?.postTokenBalances.find((balance) => { if (originalBalance?.owner && originalBalance.owner === balance.owner) { return false; } if (!balance.uiTokenAmount.uiAmount) { return false; } return balance.uiTokenAmount.uiAmount > 0; }); return Boolean(balanceWithToken); } function getTokenDestinationFromTx( tx: ParsedConfirmedTransaction ): string | undefined { if (!tx.meta?.postTokenBalances?.length) { return; } let destinationBalance = tx.meta?.postTokenBalances.find((balance) => { if (!balance.uiTokenAmount.uiAmount) { return false; } return balance.uiTokenAmount.uiAmount > 0; }); if (destinationBalance) { return (destinationBalance as TokenBalance & { owner?: string }).owner; } return; } function getTokenFromMeta( meta: ParsedConfirmedTransactionMeta ): string | undefined { if (meta.preTokenBalances && meta.preTokenBalances[0]?.mint) { return meta.preTokenBalances[0]?.mint; } if (meta.postTokenBalances && meta.postTokenBalances[0]?.mint) { return meta.postTokenBalances[0]?.mint; } return; } function getPriceInLamportForSolanaArt( { preBalances, postBalances }: ParsedConfirmedTransactionMeta, accountKeys: ParsedMessageAccount[], buyer: string ): number { const transferValues = accountKeys.reduce( (transferValues, current, currentIndex, arr) => { const value = Math.abs( postBalances[currentIndex] - preBalances[currentIndex] ); if (current.pubkey.toString() === buyer) { transferValues.buyerTransfer = value; } transferValues.highestTransfer = Math.max( transferValues.highestTransfer, value ); return transferValues; }, { highestTransfer: 0, buyerTransfer: 0, } ); return transferValues.highestTransfer - transferValues.buyerTransfer; } /** * Guessing the seller from transfers by assuming the seller always get the biggest * cut of the revenue from the sale */ function guessSellerByTransfers(transfers: Transfer[]): string | undefined { if (!transfers.length) { return; } const saleTransfers = [...transfers]; return saleTransfers.sort((t1, t2) => { if (t1.revenue.amount > t2.revenue.amount) { return -1; } if (t1.revenue.amount < t2.revenue.amount) { return 1; } return 0; })[0].to; } function findLargestInnerInstructionIndex( innerInstructions: ParsedInnerInstruction[] ) { return innerInstructions.reduce((prevIndex, current, currentIndex) => { const prevInstruction = innerInstructions[prevIndex]; if (current.instructions.length > prevInstruction.instructions.length) { return currentIndex; } return prevIndex; }, 0); } export async function parseNFTSaleOnTx( web3Conn: Connection, txResp: ParsedConfirmedTransaction, marketplace: Marketplace, transferInstructionIndex?: number ): Promise { if (!txResp?.blockTime) { return null; } if (!txResp.meta) { return null; } if (txResp.meta.err) { return null; } const signer = txResp.transaction.message.accountKeys.find((k) => { return k.signer; }); if (!signer) { return null; } const signerAddress = signer.pubkey.toString(); // A sale transaction should move the token from one account to another if (!wasTokenMovedInTx(txResp)) { return null; } // Setting the signer as the default buyer and direct purchases as the default fallback // It's true in most cases let buyer = signerAddress; let buyMethod = SaleMethod.Direct; const tokenDestination = getTokenDestinationFromTx(txResp); if (tokenDestination && tokenDestination !== buyer) { buyer = tokenDestination; buyMethod = SaleMethod.Bid; } const transactionExecByMarketplaceProgram = txContainsLog( txResp, marketplace.programId ); if (!transactionExecByMarketplaceProgram) { return null; } const { meta: { innerInstructions }, } = txResp; if (!innerInstructions) { return null; } if (typeof transferInstructionIndex == "undefined") { transferInstructionIndex = findLargestInnerInstructionIndex(innerInstructions); } if (innerInstructions.length < transferInstructionIndex + 1) { return null; } const token = getTokenFromMeta(txResp.meta); if (!token) { return null; } const nftData = await fetchNFTData(web3Conn, token); if (!nftData) { return null; } let priceInLamport = 0; let transfers = getTransfersFromInnerInstructions( innerInstructions[transferInstructionIndex] ); if (!transfers.length) { if (marketplace === solanart && txContainsLog(txResp, ["Accept Offer"])) { /** * Solanart bidding purchase transaction doesn't use transfers to distribute royalties * Which is why this method needs a special condition for extracting the price */ priceInLamport = getPriceInLamportForSolanaArt( txResp.meta, txResp.transaction.message.accountKeys, buyer ); } } else if (transfers.length === 1) { // There should be more than one transfers as all NFT contains royalties and seller revenue return null; } else { priceInLamport = transfers.reduce((prev, current) => { return prev + current.revenue.amount; }, 0); } if (!priceInLamport) { return null; } const seller = guessSellerByTransfers(transfers); // There are many cases that lamport stored contains floating points // For example: https://explorer.solana.com/tx/5YHfVoe9jSBTa3FWcYV11i6MNtPALTpot1ca6PydLx4nGNyCPc7cghwbz6VXgAyMrxUZDkkp2QoYfot74ckLsUYG // Generally, there should be no reason for the last digit of lamport not to be 0 // Rounding it here ensures we get a more accurate result for sale. // That's what the explorers do. priceInLamport = Math.round(priceInLamport / 10) * 10; return { transaction: txResp.transaction.signatures[0], buyer, seller, method: buyMethod, transfers, token, nftData, soldAt: new Date(txResp.blockTime * 1000), getPriceInLamport(): number { return priceInLamport; }, getPriceInSOL() { return priceInLamport / LamportPerSOL; }, marketplace, }; } ================================================ FILE: src/lib/marketplaces/index.ts ================================================ export * from "./types"; export { default as parseNFTSale } from "./parseNFTSaleForAllMarkets"; export { default } from "./marketplaces"; ================================================ FILE: src/lib/marketplaces/magicEden.test.ts ================================================ import magicEden from "./magicEden"; jest.mock("lib/solana/NFTData", () => { return { fetchNFTData: () => { return {}; }, }; }); describe("magicEden", () => { test("itemUrl", () => { expect(magicEden.itemURL("xxx1")).toEqual( "https://magiceden.io/item-details/xxx1" ); }); }); ================================================ FILE: src/lib/marketplaces/magicEden.ts ================================================ import { Marketplace, NFTSale } from "./types"; import { parseNFTSaleOnTx } from "lib/marketplaces/helper"; const magicEden: Marketplace = { name: "Magic Eden", programId: [ "MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8", "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K", ], iconURL: "https://www.magiceden.io/img/favicon.png", itemURL: (token: String) => `https://magiceden.io/item-details/${token}`, profileURL: (address: String) => `https://magiceden.io/u/${address}`, // Deprecated MagicEden doesn't work with the existing ways of parsing NFT sales // Detecting MagicEden now happens via their API parseNFTSale(web3Conn, txResp): Promise { return parseNFTSaleOnTx(web3Conn, txResp, this); }, }; export default magicEden; ================================================ FILE: src/lib/marketplaces/marketplaces.ts ================================================ import { Marketplace } from "./types"; import magicEden from "./magicEden"; import digitalEyes from "./digitalEyes"; import solanart from "./solanart"; import alphaArt from "./alphaArt"; import exchangeArt from "./exchangeArt"; import solsea from "./solsea"; import openSea from "./openSea"; /** * These are the list of marketplaces that we check for notifications */ const marketplaces: Marketplace[] = [ magicEden, digitalEyes, solanart, alphaArt, exchangeArt, solsea, openSea, ]; export default marketplaces; ================================================ FILE: src/lib/marketplaces/openSea.test.ts ================================================ import openSea from "./openSea"; import openSeaSaleTx from "./__fixtures__/openSeaSaleTx"; import openSeaSale2Tx from "./__fixtures__/openSeaSale2Tx"; import openSeaSale3Tx from "./__fixtures__/openSeaSale3Tx"; import openSeaBidTx from "./__fixtures__/openSeaBidTx"; import { Connection } from "@solana/web3.js"; jest.mock("lib/solana/NFTData", () => { return { fetchNFTData: () => { return {}; }, }; }); describe("openSea", () => { const conn = new Connection("https://test/"); test("itemUrl", () => { expect(openSea.itemURL("xxx1")).toEqual( "https://opensea.io/assets/solana/xxx1" ); }); describe("parseNFTSale", () => { test("sale transaction should return NFTSale", async () => { const sale = await openSea.parseNFTSale(conn, openSeaSaleTx); if (!sale) { fail("did not return NFTSale"); } expect(sale.transaction).toEqual( "3uCUHGPcXJGA4c1fwwY2hn4pdfLYqUuqACqGHaWhPjCqt8YJrZ63QQrPqFn56qe3QEoL7BJtvQA8VuTCV4QPrEA2" ); expect(sale.token).toEqual( "CL8vqe2dL8Khh1fZtzSZL6DcXweSkdzGVS4t8LbmBh14" ); expect(sale.soldAt).toEqual(new Date(1649206880 * 1000)); expect(sale.marketplace).toEqual(openSea); expect(sale.getPriceInLamport()).toEqual(94000000000); expect(sale.getPriceInSOL()).toEqual(94); }); test("sale transaction v2 should return NFTSale", async () => { const sale = await openSea.parseNFTSale(conn, openSeaSale2Tx); if (!sale) { fail("did not return NFTSale"); } expect(sale.transaction).toEqual( "4frBMA4q4i11YxxpqNhFaygRuC6wa1XW8KHJwMWCCp3C6piXAWmSGinot7XiBXPqTTcnLGJkgag9Kvuz4gkiMrnX" ); expect(sale.token).toEqual( "CiRHyMF2zUdfqJ5x6ixQnDiPJw4CcWWGmdqS2YQiFd88" ); }); test("sale transaction v3 should return NFTSale", async () => { const sale = await openSea.parseNFTSale(conn, openSeaSale3Tx); if (!sale) { fail("did not return NFTSale"); } expect(sale.transaction).toEqual( "66EfiWJrPWzdu4BqFAff1Eov7JQfUrfMbmmxAKEx6QqrS2D6zm5XbsCP5yq3RnaUzUDxc5tWJBChBjmhWNFXzmaR" ); expect(sale.token).toEqual( "FfiAdK89m762LxdCQTjdKB4qyH77PMzhgt2wbP5SGg6V" ); }); test("non-sale transaction should return null", async () => { const invalidSaleTx = { ...openSeaSaleTx, meta: { ...openSeaSaleTx.meta, preTokenBalances: [], postTokenBalances: [], }, }; expect(await openSea.parseNFTSale(conn, invalidSaleTx)).toBe(null); }); test("bidding transaction should return null", async () => { expect(await openSea.parseNFTSale(conn, openSeaBidTx)).toBe(null); }); test("non OpenSea transaction", async () => { const invalidSaleTx = { ...openSeaSaleTx, }; invalidSaleTx.meta.logMessages = ["Program xxx invoke [1]"]; expect(await openSea.parseNFTSale(conn, invalidSaleTx)).toBe(null); }); }); }); ================================================ FILE: src/lib/marketplaces/openSea.ts ================================================ import { Marketplace, NFTSale } from "./types"; import { parseNFTSaleOnTx } from "./helper"; const openSea: Marketplace = { name: "OpenSea", programId: ["hausS13jsjafwWwGqZTUQRmWyvyxn9EQpqMwV1PBBmk"], iconURL: "https://storage.googleapis.com/opensea-static/Logomark/Logomark-Blue.png", itemURL: (token: String) => `https://opensea.io/assets/solana/${token}`, profileURL: (address: String) => `https://opensea.io/${address}`, parseNFTSale(web3Conn, txResp): Promise { return parseNFTSaleOnTx(web3Conn, txResp, this); }, }; export default openSea; ================================================ FILE: src/lib/marketplaces/parseNFTSaleForAllMarkets.test.ts ================================================ import magicEdenSaleTx from "./__fixtures__/magicEdenSaleTx"; import magicEdenSaleTxV2 from "./__fixtures__/magicEdenSaleTxV2"; import parseNFTSaleForAllMarkets from "./parseNFTSaleForAllMarkets"; import alphaArtSaleTx from "./__fixtures__/alphaArtSaleTx"; import solanartSaleTx from "./__fixtures__/solanartSaleTx"; import digitalEyeSaleTx from "./__fixtures__/digitalEyesSaleTx"; import exchangeArtSaleTx from "./__fixtures__/exchangeArtSaleTx"; import solseaSaleTx from "./__fixtures__/solseaSaleTx"; import { Connection } from "@solana/web3.js"; import openSeaSaleTx from "./__fixtures__/openSeaSaleTx"; jest.mock("lib/solana/NFTData", () => { return { fetchNFTData: () => { return {}; }, }; }); describe("parseNFTSale", () => { const conn = new Connection("https://test/"); test("sale transaction should return NFTSale", async () => { const tests = [ digitalEyeSaleTx, solanartSaleTx, alphaArtSaleTx, exchangeArtSaleTx, solseaSaleTx, openSeaSaleTx, ].map(async (tx) => { const sale = await parseNFTSaleForAllMarkets(conn, tx); expect(sale?.transaction).toEqual(tx.transaction.signatures[0]); }); return Promise.all(tests); }); test("non-sale transaction should return null", async () => { const invalidSaleTx = { ...magicEdenSaleTx, meta: { ...magicEdenSaleTx.meta, preTokenBalances: [], postTokenBalances: [], }, }; expect(await parseNFTSaleForAllMarkets(conn, invalidSaleTx)).toBe(null); }); }); ================================================ FILE: src/lib/marketplaces/parseNFTSaleForAllMarkets.ts ================================================ import { NFTSale } from "./types"; import marketplaces from "./index"; import { Connection, ParsedConfirmedTransaction } from "@solana/web3.js"; export default async function parseNFTSaleForAllMarkets( web3Conn: Connection, tx: ParsedConfirmedTransaction ): Promise { for (let i = 0; i < marketplaces.length; i++) { const marketplace = marketplaces[i]; if (!marketplace.parseNFTSale) { continue; } const nftSale = await marketplace.parseNFTSale(web3Conn, tx); if (nftSale) { return nftSale; } } return null; } ================================================ FILE: src/lib/marketplaces/solanart.test.ts ================================================ import solanart from "./solanart"; import solanartSaleTx from "./__fixtures__/solanartSaleTx"; import solanartSaleFromBidTx from "./__fixtures__/solanartSaleFromBidTx"; import solanartListingTx from "./__fixtures__/solanartListingTx"; import { SaleMethod } from "./types"; import { Connection } from "@solana/web3.js"; import solanartBidTx from "./__fixtures__/solanartBidTx"; import solanartDelistingTx from "./__fixtures__/solanartDelistingTx"; jest.mock("lib/solana/NFTData", () => { return { fetchNFTData: () => { return {}; }, }; }); describe("solanart", () => { const conn = new Connection("https://test/"); test("itemUrl", () => { expect(solanart.itemURL("xxx1")).toEqual("https://solanart.io/nft/xxx1"); }); describe("parseNFTSale", () => { test("sale transaction should return NFTSale", async () => { const sale = await solanart.parseNFTSale(conn, solanartSaleTx); expect(sale.transaction).toEqual( "3qmi5w4ZJsf1PJED21bNVpwgobcMFxUeb6coKJNA32F1fW5WELDXAxnjLzsfnxGnKQfKLuwVBk3xD6zbcjvA9GTX" ); expect(sale.token).toEqual( "2se1H9trBxHVTeiCpuk4manbaq1b4iio2MYWcLCnLMFa" ); expect(sale.soldAt).toEqual(new Date(1635558562 * 1000)); expect(sale.marketplace).toEqual(solanart); expect(sale.getPriceInLamport()).toEqual(19700000000); expect(sale.getPriceInSOL()).toEqual(19.7); const expectedTransfers = [ { to: "8Kag8CqNdCX55s4A5W4iraS71h6mv6uTHqsJbexdrrZm", from: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", revenue: { amount: 640250000, symbol: "lamport" }, }, { to: "aury7LJUae7a92PBo35vVbP61GX8VbyxFKausvUtBrt", from: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", revenue: { amount: 344750000, symbol: "lamport" }, }, { to: "E6dkaYhqbZN3a1pDrdbajJ9D8xA66LBBcjWi6dDNAuJH", from: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", revenue: { amount: 591000000, symbol: "lamport" }, }, { to: "H9Yi8cfwvwKJvpLMPTLftPdVkvmzkN7BamcAT5hyEh8j", from: "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P", revenue: { amount: 18124000000, symbol: "lamport" }, }, ]; expect(sale.transfers.length).toEqual(expectedTransfers.length); expectedTransfers.forEach((expectedTransfer, index) => { const transfer = sale.transfers[index]; expect(transfer.from).toEqual(expectedTransfer.from); expect(transfer.to).toEqual(expectedTransfer.to); expect(transfer.revenue).toEqual(expectedTransfer.revenue); }); }); test("bidding sale transaction should return NFTSale", async () => { const sale = await solanart.parseNFTSale(conn, solanartSaleFromBidTx); expect(sale.transaction).toEqual( "4PJ7X1ZCEj68n2HXfVx48jGnqgu9rWAxquVihpNvDizbZ5V5vUHViz2N54HHMUiBvKtx7mbmYAQ4unURg9YEgLM6" ); expect(sale.token).toEqual( "HRGYe4hDNjNVCjmwhmnEiiZtbjzShCwazC1JEyERXRUo" ); expect(sale.method).toEqual(SaleMethod.Bid); expect(sale.buyer).toEqual( "6bPDVYs5Ewutp8jqurwqfWkL3UeUAGouZg5RJxNY2yAM" ); expect(sale.getPriceInSOL()).toEqual(4.5); }); test("non-sale transaction should return null", async () => { const invalidSaleTx = { ...solanartSaleTx, meta: { ...solanartSaleTx.meta, preTokenBalances: [], postTokenBalances: [], }, }; expect(await solanart.parseNFTSale(conn, invalidSaleTx)).toBe(null); }); test("listing transaction should return null", async () => { expect(await solanart.parseNFTSale(conn, solanartListingTx)).toBe(null); }); test("bid transaction should return null", async () => { expect(await solanart.parseNFTSale(conn, solanartBidTx)).toBe(null); }); test("delist transaction should return null", async () => { expect(await solanart.parseNFTSale(conn, solanartDelistingTx)).toBe(null); }); test("non Solanart transaction", async () => { const invalidSaleTx = { ...solanartSaleTx, }; invalidSaleTx.meta.logMessages = ["Program xxx invoke [1]"]; expect(await solanart.parseNFTSale(conn, invalidSaleTx)).toBe(null); }); }); }); ================================================ FILE: src/lib/marketplaces/solanart.ts ================================================ import { Marketplace, NFTSale } from "./types"; import { parseNFTSaleOnTx } from "./helper"; const solanart: Marketplace = { name: "Solanart", programId: ["CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz"], iconURL: "https://solanart.io/logo192.png", itemURL: (token: String) => `https://solanart.io/nft/${token}`, profileURL: (address: String) => `https://explorer.solana.com/address/${address}`, parseNFTSale(web3Conn, txResp): Promise { return parseNFTSaleOnTx(web3Conn, txResp, this); }, }; export default solanart; ================================================ FILE: src/lib/marketplaces/solsea.test.ts ================================================ import solsea from "./solsea"; import solseaSaleTx from "./__fixtures__/solseaSaleTx"; import { Connection } from "@solana/web3.js"; jest.mock("lib/solana/NFTData", () => { return { fetchNFTData: () => { return {}; }, }; }); describe("solsea", () => { const conn = new Connection("https://test/"); test("itemUrl", () => { expect(solsea.itemURL("xxx1")).toEqual("https://solsea.io/nft/xxx1"); }); describe("parseNFTSale", () => { test("sale transaction should return NFTSale", async () => { const sale = await solsea.parseNFTSale(conn, solseaSaleTx); if (!sale) { fail("did not return NFTSale"); } expect(sale.transaction).toEqual( "4XuN4e8nDz6jpCB6YXEBP7i3EFaoN9hVGkxMRTJeuu2i9dMZ7rJKCwU9A5zN8DoPw9dm5zbVrJwSfw5xctyJ82GU" ); expect(sale.token).toEqual( "8gaYezSKFxJu4Q7F7xLWTbFBLAEsKefqq9i8stML7B6S" ); expect(sale.soldAt).toEqual(new Date(1638570298 * 1000)); expect(sale.marketplace).toEqual(solsea); expect(sale.getPriceInLamport()).toEqual(3000000000); expect(sale.getPriceInSOL()).toEqual(3); }); test("non-sale transaction should return null", async () => { const invalidSaleTx = { ...solseaSaleTx, meta: { ...solseaSaleTx.meta, preTokenBalances: [], postTokenBalances: [], }, }; expect(await solsea.parseNFTSale(conn, invalidSaleTx)).toBe(null); }); test("non Solsea transaction", async () => { const invalidSaleTx = { ...solseaSaleTx, }; invalidSaleTx.meta.logMessages = ["Program xxx invoke [1]"]; expect(await solsea.parseNFTSale(conn, invalidSaleTx)).toBe(null); }); }); }); ================================================ FILE: src/lib/marketplaces/solsea.ts ================================================ import { Marketplace, NFTSale } from "./types"; import { parseNFTSaleOnTx } from "./helper"; const solsea: Marketplace = { name: "Solsea", programId: ["617jbWo616ggkDxvW1Le8pV38XLbVSyWY8ae6QUmGBAU"], iconURL: "https://solsea.io/logo_solo.svg", itemURL: (token: String) => `https://solsea.io/nft/${token}`, profileURL: (address: String) => `https://explorer.solana.com/address/${address}`, parseNFTSale(web3Conn, txResp): Promise { return parseNFTSaleOnTx(web3Conn, txResp, this, 0); }, }; export default solsea; ================================================ FILE: src/lib/marketplaces/types.ts ================================================ import { Connection, ParsedConfirmedTransaction } from "@solana/web3.js"; import { MagicEdenConfig } from "config"; import NFTData from "lib/solana/NFTData"; export enum SaleMethod { Direct = "direct", Bid = "bid", } export interface Marketplace { name: string; programId: string[]; iconURL: string; itemURL: (token: String) => string; profileURL: (address: String) => string; parseNFTSale?: ( web3Conn: Connection, tx: ParsedConfirmedTransaction ) => Promise; } export interface Transfer { from: string; to: string; revenue: { amount: number; symbol: string; }; } export interface NFTSale { transaction: string; buyer: string; seller?: string; method: SaleMethod; token: string; transfers: Transfer[]; soldAt: Date; marketplace: Marketplace; nftData?: NFTData; getPriceInLamport: () => number; getPriceInSOL: () => number; } ================================================ FILE: src/lib/notifier/index.ts ================================================ export * from "./notifier"; ================================================ FILE: src/lib/notifier/notifier.test.ts ================================================ import {newNotifierFactory, NotificationType} from "./notifier"; import {loadConfig} from "config"; import notifyDiscordSale from 'lib/discord/notifyDiscordSale'; import notifyTwitter from 'lib/twitter/notifyTwitter'; import queue from "queue"; jest.mock('lib/discord'); jest.mock("lib/twitter/notifyTwitter", () => { return jest.fn(); }); jest.mock("lib/discord/notifyDiscordSale", () => { return jest.fn(); }); describe("notifier", () => { beforeEach(() => { jest.clearAllMocks(); }); const nQueue = queue({ autostart: true, }) it("notify with discord client", async () => { const factory = await newNotifierFactory({ ...(loadConfig({})), discordBotToken: 'test-token-1', }, nQueue); const notifier = await factory.create({ mintAddress: 'add-xxaa-12', discordChannelId: 'test', }); await notifier.notify(NotificationType.Sale, {}); expect(notifyDiscordSale).toHaveBeenCalledTimes(1); expect(notifyTwitter).toHaveBeenCalledTimes(0); }); it("notify with twitter client", async () => { jest.unmock('lib/discord'); const factory = await newNotifierFactory({ ...(loadConfig({})), twitter: { appKey: 'app-x', appSecret: 'app-secret-1', accessSecret: 'xx-1', accessToken: 'token', }, }, nQueue); const notifier = await factory.create({ mintAddress: 'add-xxaa-12', discordChannelId: 'test', }); await notifier.notify(NotificationType.Sale, {}); expect(notifyDiscordSale).toHaveBeenCalledTimes(0); expect(notifyTwitter).toHaveBeenCalledTimes(1); }); }); ================================================ FILE: src/lib/notifier/notifier.ts ================================================ import {Config} from "config"; import { initClient as initDiscordClient } from "lib/discord"; import initTwitterClient from "lib/twitter"; import notifyDiscordSale from "lib/discord/notifyDiscordSale"; import notifyTwitter from "lib/twitter/notifyTwitter"; import { Project } from "workers/notifyNFTSalesWorker"; import logger from "lib/logger"; import queue from "queue"; import Discord from "discord.js"; export enum NotificationType { Sale, } export interface Notifier { notify: (nType: NotificationType, data: any) => Promise; } export enum Platform { Twitter = "Twitter", Discord = "Discord", Webhook = "Webhook", } function queueNotification( nQueue: queue, platform: Platform, callback: () => Promise ) { nQueue.push(() => { try { return callback(); } catch (err) { logNotificationError(err, platform); } }); } export async function newNotifierFactory(config: Config, nQueue: queue) { let discordClient:Discord.Client; if (config.discordBotToken) { discordClient = await initDiscordClient(config.discordBotToken); } const twitterClient = await initTwitterClient(config.twitter); return { create(project: Project): Notifier { async function notifySale(data: any) { if (discordClient) { queueNotification(nQueue, Platform.Discord, async () => { await notifyDiscordSale( discordClient, project.discordChannelId, data ); }); } if (twitterClient) { queueNotification(nQueue, Platform.Twitter, async () => { await notifyTwitter(twitterClient, data); }); } } return { async notify(nType: NotificationType, data: any) { if (nType === NotificationType.Sale) { await notifySale(data); return; } }, }; }, }; } function logNotificationError(err: unknown, platform: string) { logger.error(`Error occurred when notifying ${platform}`, err); } ================================================ FILE: src/lib/sleep/index.ts ================================================ export {default} from './sleep'; ================================================ FILE: src/lib/sleep/sleep.ts ================================================ export default async function sleep(ms: number) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } ================================================ FILE: src/lib/solana/NFTData.ts ================================================ import { Metaplex } from "@metaplex-foundation/js"; import { Connection, PublicKey } from "@solana/web3.js"; import logger from "lib/logger"; export default interface NFTData { name: string; symbol: string; image: string; sellerFeeBasisPoints: number; } export async function fetchNFTData( web3Conn: Connection, token: string ): Promise { const metaplex = new Metaplex(web3Conn); try { const metadata = await metaplex.nfts().findByMint({ mintAddress: new PublicKey(token), loadJsonMetadata: true, }); if (!metadata.json) { return; } return { name: metadata.json.name || "", symbol: metadata.json.symbol || "", image: metadata.json.image || "", sellerFeeBasisPoints: metadata.json.seller_fee_basis_points || 0, }; } catch (e) { logger.error("fetch NFT data failed", e); } } ================================================ FILE: src/lib/solana/connection.ts ================================================ import { ConfirmedSignaturesForAddress2Options, Connection, ConnectionConfig, ParsedTransactionWithMeta, PublicKey, } from "@solana/web3.js"; export const maxSupportedTransactionVersion = 2; export function newConnection(): Connection { const config: ConnectionConfig = {}; if (process.env.SOLANA_RPC_KEY_SECRET) { config.httpHeaders = { Authorization: process.env.SOLANA_RPC_KEY_SECRET }; } return new Connection(process.env.SOLANA_RPC || "", config); } interface Opt extends ConfirmedSignaturesForAddress2Options { onTransaction?: (tx: ParsedTransactionWithMeta) => Promise; } export async function fetchWeb3Transactions( conn: Connection, account: string, opt?: Opt ): Promise { const signatures = await conn.getConfirmedSignaturesForAddress2( new PublicKey(account), { limit: opt?.limit, before: opt?.before, until: opt?.until, }, "finalized" ); if (signatures) { const txs: ParsedTransactionWithMeta[] = []; const oldestToLatest = signatures.reverse(); for (let i = 0; i < oldestToLatest.length; i++) { const signature = oldestToLatest[i]; const tx = await conn.getParsedTransaction(signature.signature, { commitment: "finalized", maxSupportedTransactionVersion, }); if (!tx) { continue; } opt?.onTransaction && (await opt.onTransaction(tx)); txs.push(tx); } return txs; } return null; } ================================================ FILE: src/lib/solana/index.ts ================================================ export * from "./connection"; export const LamportPerSOL = 1000000000; ================================================ FILE: src/lib/truncateForAddress.ts ================================================ export default function truncateForAddress(str: String): string { return str.substring(0, 6) + "..." + str.substring(str.length - 6); } ================================================ FILE: src/lib/twitter/index.ts ================================================ import TwitterApi, { TwitterApiTokens } from "twitter-api-v2"; async function initTwitterClient(tokens: TwitterApiTokens) { if ( !tokens.appKey || !tokens.appSecret || !tokens.accessToken || !tokens.accessSecret ) { return null; } return new TwitterApi(tokens); } export default initTwitterClient; ================================================ FILE: src/lib/twitter/notifyTwitter.ts ================================================ import TwitterAPI from "twitter-api-v2"; import { NFTSale, SaleMethod } from "lib/marketplaces"; import axios from "axios"; export default async function notifyTwitter( twitterClient: TwitterAPI, nftSale: NFTSale ) { const nftName = nftSale.nftData?.name; const text = `${nftName} has just been sold ${ nftSale.method === SaleMethod.Bid ? "via bidding " : "" }for ${nftSale.getPriceInSOL()} S◎L at ${ nftSale.marketplace.name }! #SolanaNFTs #NFTSale`; const mediaArr: string[] = []; if (Boolean(nftSale.nftData?.image)) { const data = await getImageDataFromUrl(nftSale.nftData?.image as string); const media = await twitterClient.v1.uploadMedia(data, { type: await getDataType(data), }); mediaArr.push(media); } return twitterClient.v1.tweet(text, { media_ids: mediaArr, }); } async function getDataType(buffer: Buffer) { // reason why the import is here: https://github.com/sindresorhus/file-type/issues/525 const { fromBuffer } = await import("file-type"); const result = await fromBuffer(buffer); return result ? result.ext : undefined; } async function getImageDataFromUrl(url: string) { const img = await axios.get(url, { responseType: "arraybuffer" }); return img.data as Buffer; } ================================================ FILE: src/server.ts ================================================ import express from "express"; import { initClient as initDiscordClient } from "lib/discord"; import initWorkers from "workers/initWorkers"; import { maxSupportedTransactionVersion, newConnection, } from "lib/solana/connection"; import dotenv from "dotenv"; import notifyDiscordSale, { getStatus } from "lib/discord/notifyDiscordSale"; import { Env, loadConfig } from "config"; import { Worker } from "workers/types"; import notifyNFTSalesWorker from "workers/notifyNFTSalesWorker"; import notifyMagicEdenNFTSalesWorker from "workers/notifyMagicEdenNFTSalesWorker"; import { parseNFTSale } from "lib/marketplaces"; import { ParsedTransactionWithMeta } from "@solana/web3.js"; import notifyTwitter from "lib/twitter/notifyTwitter"; import logger from "lib/logger"; import { newNotifierFactory } from "lib/notifier"; import initTwitterClient from "lib/twitter"; import queue from "queue"; (async () => { try { const result = dotenv.config(); if (result.error) { throw result.error; } const config = loadConfig(process.env as Env); const { subscriptions } = config; const port = process.env.PORT || 4000; const web3Conn = newConnection(); const nQueue = queue({ concurrency: config.queueConcurrency, autostart: true, }); const notifierFactory = await newNotifierFactory(config, nQueue); const server = express(); server.get("/", (req, res) => { const { totalNotified, lastNotified } = getStatus(); res.send(` ${subscriptions.map( (s) => `Watching the address ${s.mintAddress} at discord channel #${s.discordChannelId} for NFT sales.
` )} Total notifications sent: ${totalNotified}
${ lastNotified ? `Last notified at: ${lastNotified.toISOString()}
` : "" } ${`Current UTC time: ${new Date().toISOString()}`} `); }); server.get("/test-sale-tx", async (req, res) => { const signature = (req.query["signature"] as string) || ""; if (!signature) { res.send(`no signature in query param`); return; } let tx: ParsedTransactionWithMeta | null = null; try { tx = await web3Conn.getParsedTransaction(signature, { commitment: "finalized", maxSupportedTransactionVersion, }); } catch (e) { logger.log(e); res.send(`Get transaction failed, check logs for error.`); return; } if (!tx) { res.send(`No transaction found for ${signature}`); return; } const nftSale = await parseNFTSale(web3Conn, tx); if (!nftSale) { res.send( `No NFT Sale detected for tx: ${signature}\n${JSON.stringify(tx)}` ); return; } if (config.discordBotToken) { const discordClient = await initDiscordClient(config.discordBotToken); if (discordClient) { const channelId = (req.query["channelId"] as string) || ""; await notifyDiscordSale(discordClient, channelId, nftSale); } } const twitterClient = await initTwitterClient(config.twitter); const sendTweet = (req.query["tweet"] as string) || ""; if (sendTweet && twitterClient) { await notifyTwitter(twitterClient, nftSale).catch((err) => { logger.error("Error occurred when notifying twitter", err); }); } res.send(`NFT Sales parsed: \n${JSON.stringify(nftSale)}`); }); server.listen(port, (err?: any) => { if (err) throw err; logger.log(`Ready on http://localhost:${port}`); }); let workers: Worker[] = []; if (subscriptions.length) { workers = subscriptions.map((s) => { const project = { discordChannelId: s.discordChannelId, mintAddress: s.mintAddress, }; const notifier = notifierFactory.create(project); return notifyNFTSalesWorker(notifier, web3Conn, project); }); } if (config.magicEdenConfig.collection) { const notifier = notifierFactory.create({ discordChannelId: config.magicEdenConfig?.discordChannelId, mintAddress: "", }); workers.push( notifyMagicEdenNFTSalesWorker( notifier, web3Conn, config.magicEdenConfig ) ); } const _ = initWorkers(workers, () => { // Add randomness between worker executions so the requests are not made all at once return Math.random() * 5000; // 0-5s }); } catch (e) { logger.error(e); process.exit(1); } })(); ================================================ FILE: src/workers/initWorkers.test.ts ================================================ import initWorkers from "./initWorkers"; import { Worker } from "./types"; jest.useFakeTimers(); jest.spyOn(global, "setInterval"); describe("initWorkers", () => { async function sleep(ms: number) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } test("run", () => { const mockWorker: Worker = { async execute() {}, }; jest.spyOn(mockWorker, "execute"); initWorkers([mockWorker]); expect(mockWorker.execute).toHaveBeenCalledTimes(1); jest.runOnlyPendingTimers(); expect(mockWorker.execute).toHaveBeenCalledTimes(2); }); test("run after recover from error", () => { const mockWorker: Worker = { async execute() { await sleep(20); throw "error"; }, }; jest.spyOn(mockWorker, "execute"); initWorkers([mockWorker]); expect(mockWorker.execute).toHaveBeenCalledTimes(1); jest.runOnlyPendingTimers(); expect(mockWorker.execute).toHaveBeenCalledTimes(2); }); }); ================================================ FILE: src/workers/initWorkers.ts ================================================ import { Worker } from "./types"; import logger from "lib/logger"; import sleep from "lib/sleep"; const defaultInterval = 1000 * 60; // 1 minutes export default async function initWorkers( workers: Worker[], delayInMs?: () => number, interval: number = defaultInterval ) { if (!workers.length) { throw "Cannot init workers because no workers are configured: check env vars"; } logger.log(`starting ${workers.length} worker(s)...`); const runWorkers = async () => { const promises = workers.map(async (w) => { if (delayInMs) { await sleep(delayInMs()); } try { return await w.execute(); } catch (e) { logger.warn(e); } }); return Promise.all(promises); }; const _ = runWorkers(); setInterval(runWorkers, interval); } ================================================ FILE: src/workers/notifyMagicEdenNFTSalesWorker.test.ts ================================================ import { NotificationType } from "lib/notifier"; import { MagicEdenConfig } from "config"; import { CollectionActivity } from "lib/marketplaces"; jest.mock("lib/solana/NFTData", () => { return { fetchNFTData: () => { return {}; }, }; }); jest.mock("axios", () => { return { get: () => { return { data: [ { type: "buyNow", blockTime: 96292000003, tokenMint: "tokenxxx2", signature: "signature-2", source: "xxx", collection: "mlk", buyer: "buyer-2", seller: "seller-2", price: 0.2, }, { type: "buyNow", blockTime: 96292000001, tokenMint: "tokenxxx1", signature: "signature-1", source: "xxx", collection: "mlk", buyer: "buyer-1", seller: "seller-1", price: 0.2, }, ] as CollectionActivity[], }; }, }; }); import newWorker from "./notifyMagicEdenNFTSalesWorker"; import { Connection } from "@solana/web3.js"; describe("notifyMagicEdenNFTSalesWorker", () => { afterEach(() => { jest.clearAllMocks(); }); describe("execute", () => { const notifier = { notify: jest.fn(), }; const conn = new Connection("https://test/"); test("on sale activity", async () => { const config: MagicEdenConfig = { url: "https://magiceden.io", collection: "mlk", discordChannelId: "", }; const worker = newWorker(notifier, conn, config); await worker.execute(); expect(notifier.notify.mock.calls.length).toEqual(2); const expectedArgs = notifier.notify.mock.calls[0]; expect(expectedArgs[0]).toEqual(NotificationType.Sale); expect(expectedArgs[1].buyer).toEqual("buyer-1"); // Should fires the earliest sale first await worker.execute(); expect(notifier.notify.mock.calls.length).toEqual(2); }); }); }); ================================================ FILE: src/workers/notifyMagicEdenNFTSalesWorker.ts ================================================ import axios from "axios"; import { MagicEdenConfig } from "config"; import { NFTSale, SaleMethod } from "lib/marketplaces"; import MagicEden from "lib/marketplaces/magicEden"; import { fetchNFTData } from "lib/solana/NFTData"; import { Worker } from "./types"; import { Connection } from "@solana/web3.js"; import logger from "lib/logger"; import { NotificationType, Notifier } from "lib/notifier"; export interface CollectionActivity { signature: string; type: string; source: string; tokenMint: string; collection: string; slot: number; blockTime: number; buyer: string; buyerReferral: string; seller?: any; sellerReferral: string; price: number; } function newNotificationsTracker(limit: number = 50) { let notifiedTxs: string[] = []; return { alreadyNotified(tx: string) { return notifiedTxs.includes(tx); }, trackNotifiedTx(tx: string) { notifiedTxs = [tx, ...notifiedTxs]; if (notifiedTxs.length > limit) { notifiedTxs.pop(); } }, }; } export default function newWorker( notifier: Notifier, web3Conn: Connection, config: MagicEdenConfig ): Worker { const timestamp = Date.now(); let notifyAfter = new Date(timestamp); /** * Keep track of the latest notifications, so we don't notify them again */ const latestNotifications = newNotificationsTracker(); return { async execute() { let activities: CollectionActivity[] = []; try { // Reference: https://api.magiceden.dev/#95fed531-fd1f-4cbb-8137-30e0f2294cd7 const res = await axios.get( `${config.url}/collections/${config.collection}/activities?offset=0&limit=100` ); activities = res.data as CollectionActivity[]; } catch (e) { logger.error(e); return; } const sortByEarliest = activities.sort( (a: CollectionActivity, b: CollectionActivity) => { return a.blockTime - b.blockTime; } ); for (let i = 0; i < sortByEarliest.length; i++) { const activity = sortByEarliest[i]; if (activity.type !== "buyNow") { continue; } const nftData = await fetchNFTData(web3Conn, activity.tokenMint); if (!nftData) { return; } const nftSale: NFTSale = { transaction: activity.signature, soldAt: new Date((activity.blockTime || 0) * 1000), seller: activity.seller, buyer: activity.buyer, token: activity.tokenMint, method: SaleMethod.Direct, marketplace: MagicEden, transfers: [], nftData, getPriceInLamport() { return activity.price / 1000000; }, getPriceInSOL() { return activity.price; }, }; if (notifyAfter > nftSale.soldAt) { return; } // Don't notify if transaction was previously notified. if (latestNotifications.alreadyNotified(nftSale.transaction)) { logger.warn(`Duplicate tx ignored: ${nftSale.transaction}`); return; } await notifier.notify(NotificationType.Sale, nftSale); latestNotifications.trackNotifiedTx(nftSale.transaction); notifyAfter = nftSale.soldAt; } }, }; } ================================================ FILE: src/workers/notifyNFTSalesWorker.test.ts ================================================ import { NotificationType } from "lib/notifier"; jest.mock("lib/solana/NFTData", () => { return { fetchNFTData: () => { return {}; }, }; }); import newWorker, { Project } from "./notifyNFTSalesWorker"; import { ConfirmedSignatureInfo, Connection } from "@solana/web3.js"; import solanartSaleTx from "lib/marketplaces/__fixtures__/solanartSaleTx"; describe("notifyNFTSalesWorker", () => { afterEach(() => { jest.clearAllMocks(); }); describe("execute", () => { const notifier = { notify: jest.fn(), }; const conn = new Connection("https://test/"); jest .spyOn(conn, "getConfirmedSignaturesForAddress2") .mockImplementation(async () => { return [ { signature: "33CJriD17bUScYW7eKFjM6BPfkFWPerHfdpvtw3a8JdN", slot: 1, } as ConfirmedSignatureInfo, { signature: "33CJriD17bUScYW7eKFjM6BPfkFWPerHfdpvtw3a8JdN", slot: 1, } as ConfirmedSignatureInfo, ]; }); jest.spyOn(conn, "getParsedTransaction").mockImplementation(async () => { return { ...solanartSaleTx, blockTime: Date.now() + 1000000, }; }); test("on solanart tx", async () => { const project: Project = { mintAddress: "A7p8451ktDCHq5yYaHczeLMYsjRsAkzc3hCXcSrwYHU7", discordChannelId: "", }; const worker = newWorker(notifier, conn, project); await worker.execute(); await worker.execute(); expect(notifier.notify.mock.calls.length).toEqual(1); const expectedArgs = notifier.notify.mock.calls[0]; expect(expectedArgs[0]).toEqual(NotificationType.Sale); expect(expectedArgs[1].buyer).toEqual( "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P" ); }); test("sale tx signed by the same mint address ", async () => { const project: Project = { mintAddress: "33CJriD17bUScYW7eKFjM6BPfkFWPerHfdpvtw3a8JdN", discordChannelId: "", }; const worker = newWorker(notifier, conn, project); await worker.execute(); expect(notifier.notify.mock.calls.length).toEqual(1); const expectedArgs = notifier.notify.mock.calls[0]; expect(expectedArgs[0]).toEqual(NotificationType.Sale); expect(expectedArgs[1].buyer).toEqual( "93ccg27u1tHK1FzqoyRtaUVh3kRwbvYNJcz4NbWWSt1P" ); }); }); }); ================================================ FILE: src/workers/notifyNFTSalesWorker.ts ================================================ import { Worker } from "./types"; import { Connection, ParsedConfirmedTransaction } from "@solana/web3.js"; import { fetchWeb3Transactions } from "lib/solana/connection"; import { parseNFTSale } from "lib/marketplaces"; import logger from "lib/logger"; import { NotificationType, Notifier } from "lib/notifier"; export interface Project { mintAddress: string; discordChannelId: string; } function getSignatureFromTx( tx?: ParsedConfirmedTransaction ): string | undefined { if (tx) { return tx.transaction.signatures[0]; } return undefined; } function newNotificationsTracker(limit: number = 50) { let notifiedTxs: string[] = []; return { alreadyNotified(tx: string) { return notifiedTxs.includes(tx); }, trackNotifiedTx(tx: string) { notifiedTxs = [tx, ...notifiedTxs]; if (notifiedTxs.length > limit) { notifiedTxs.pop(); } }, }; } export default function newWorker( notifier: Notifier, web3Conn: Connection, project: Project ): Worker { const timestamp = Date.now(); let notifyAfter = new Date(timestamp); /** * This var keeps track of the latest tx so we can optimize the rpc call */ let latestParsedTx: ParsedConfirmedTransaction | undefined; /** * Keep track of the latest notifications, so we don't notify them again */ const latestNotifications = newNotificationsTracker(); return { async execute() { await fetchWeb3Transactions(web3Conn, project.mintAddress, { limit: 50, until: getSignatureFromTx(latestParsedTx), async onTransaction(tx) { latestParsedTx = tx; const txCreatedAt = new Date((tx.blockTime || 0) * 1000); if (notifyAfter > txCreatedAt) { return; } const nftSale = await parseNFTSale(web3Conn, tx); if (!nftSale) { return; } // Don't notify if transaction was previously notified. if (latestNotifications.alreadyNotified(nftSale.transaction)) { logger.warn(`Duplicate tx ignored: ${nftSale.transaction}`); return; } // Don't notify purchases by the project's own account if (nftSale.buyer === project.mintAddress) { return; } await notifier.notify(NotificationType.Sale, nftSale); latestNotifications.trackNotifiedTx(nftSale.transaction); notifyAfter = nftSale.soldAt; }, }); }, }; } ================================================ FILE: src/workers/types.ts ================================================ export interface Worker { execute: () => Promise; } ================================================ FILE: tsconfig.json ================================================ { "compilerOptions": { "module": "commonjs", "target": "es2019", "outDir": "dist", "rootDir": "", "baseUrl": "./src", "composite": true, "declaration": true, "declarationMap": true, "sourceMap": true, "jsx": "react", "strict": true, "esModuleInterop": true, "resolveJsonModule": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "noEmit": false }, "include": ["src/**/*.ts"], "exclude": ["**/*.test.ts", "**/node_modules", "**/__fixtures__"], "ts-node": { "require": ["tsconfig-paths/register"] } }