@magiceden/magiceden-sdk
Version:
A TypeScript SDK for interacting with Magic Eden's API across multiple chains.
348 lines (347 loc) • 15.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const transactions_1 = require("../../adapters/transactions");
const web3_js_1 = require("@solana/web3.js");
const chains_1 = require("../../types/chains");
describe('SolanaTransactionAdapters', () => {
describe('fromInstructionsResponse', () => {
it('should handle versioned transaction with signed data', () => {
// Mock buffer data
const mockData = new Uint8Array([1, 0, 1, 3, 206, 211]);
const mockResponse = {
v0: {
txSigned: {
type: 'Buffer',
data: Array.from(mockData),
},
},
};
// Mock VersionedTransaction.deserialize
const deserializeSpy = jest
.spyOn(web3_js_1.VersionedTransaction, 'deserialize')
.mockImplementation(() => ({ mockTransaction: true }));
const result = transactions_1.SolanaTransactionAdapters.fromInstructionsResponse(mockResponse);
expect(deserializeSpy).toHaveBeenCalled();
expect(result).toBeInstanceOf(Array);
expect(result[0]).toEqual({
type: 'transaction',
transactionData: { mockTransaction: true },
});
deserializeSpy.mockRestore();
});
it('should handle versioned transaction with unsigned data', () => {
// Mock buffer data
const mockData = new Uint8Array([1, 0, 1, 3, 206, 211]);
const mockResponse = {
v0: {
tx: {
type: 'Buffer',
data: Array.from(mockData),
},
},
};
// Mock VersionedTransaction.deserialize
const deserializeSpy = jest
.spyOn(web3_js_1.VersionedTransaction, 'deserialize')
.mockImplementation(() => ({ mockTransaction: true }));
const result = transactions_1.SolanaTransactionAdapters.fromInstructionsResponse(mockResponse);
expect(deserializeSpy).toHaveBeenCalled();
expect(result[0]).toEqual({
type: 'transaction',
transactionData: { mockTransaction: true },
});
deserializeSpy.mockRestore();
});
it('should throw error for invalid response', () => {
const mockResponse = {};
expect(() => {
transactions_1.SolanaTransactionAdapters.fromInstructionsResponse(mockResponse);
}).toThrow('Invalid transaction response format, only versioned transactions are supported');
});
it('should throw error for legacy transaction format', () => {
const mockResponse = {
txSigned: {
type: 'Buffer',
data: [1, 0, 1, 3, 206, 211],
},
};
expect(() => {
transactions_1.SolanaTransactionAdapters.fromInstructionsResponse(mockResponse);
}).toThrow('Invalid transaction response format, only versioned transactions are supported');
});
});
describe('fromBuffer', () => {
it('should deserialize versioned transaction from buffer', () => {
// Setup
const mockBuffer = Buffer.from([1, 2, 3]);
const mockTransaction = { mockTransaction: true };
// Mock VersionedTransaction.deserialize
const deserializeSpy = jest
.spyOn(web3_js_1.VersionedTransaction, 'deserialize')
.mockReturnValue(mockTransaction);
// Call the method
const result = transactions_1.SolanaTransactionAdapters.fromBuffer(mockBuffer);
// Verify
expect(deserializeSpy).toHaveBeenCalledWith(mockBuffer);
expect(result).toBeInstanceOf(Array);
// Update expectation to match the actual structure
expect(result[0]).toEqual({
mockTransaction: true,
});
// Clean up
deserializeSpy.mockRestore();
});
it('should throw error for invalid buffer data', () => {
const mockBuffer = Buffer.from([0, 1, 2, 3]); // Invalid format
// Mock VersionedTransaction.deserialize to throw
jest.spyOn(web3_js_1.VersionedTransaction, 'deserialize').mockImplementation(() => {
throw new Error('Invalid transaction response format, only Solana transactions are supported');
});
expect(() => {
transactions_1.SolanaTransactionAdapters.fromBuffer(mockBuffer);
}).toThrow('Invalid transaction data, only versioned transactions are supported');
});
});
describe('fromV4TransactionResponse', () => {
// Mock transaction data
const mockTransactionBase64 = 'AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==';
// Valid Solana public key format for tests
const validSolanaPubkey = '11111111111111111111111111111111';
// Setup mock for VersionedTransaction.deserialize
let deserializeSpy;
beforeEach(() => {
// Remove console.log statements from the implementation for cleaner test output
jest.spyOn(console, 'log').mockImplementation(() => { });
deserializeSpy = jest
.spyOn(web3_js_1.VersionedTransaction, 'deserialize')
.mockImplementation(() => ({ mockTransaction: true }));
});
afterEach(() => {
deserializeSpy.mockRestore();
jest.restoreAllMocks();
});
// Helper function to create a valid Solana transaction step
const createValidSolanaStep = (id, feePayer, transactions) => ({
id,
chain: chains_1.Blockchain.SOLANA,
method: 'signAllAndSendTransactions',
params: {
feePayer,
transactions,
},
});
it('should handle basic V4 transaction response with signAllAndSendTransactions method', () => {
const mockResponse = {
steps: [
createValidSolanaStep('step1', validSolanaPubkey, [
{
transaction: mockTransactionBase64,
signerPubkeys: [],
},
]),
],
};
const result = transactions_1.SolanaTransactionAdapters.fromV4TransactionResponse(mockResponse);
expect(deserializeSpy).toHaveBeenCalled();
expect(result).toBeInstanceOf(Array);
expect(result).toHaveLength(1);
expect(result[0]).toEqual({
type: 'transaction',
transactionData: { mockTransaction: true },
});
});
it('should handle V4CreateLaunchpadResponse with metadata', () => {
const mockResponse = {
steps: [
createValidSolanaStep('step1', validSolanaPubkey, [
{
transaction: mockTransactionBase64,
signerPubkeys: [],
},
]),
],
metadata: {
imageUrl: 'https://example.com/image.png',
tokenImage: 'https://example.com/token.png',
metadataUrl: 'https://example.com/metadata.json',
},
};
const result = transactions_1.SolanaTransactionAdapters.fromV4TransactionResponse(mockResponse);
expect(deserializeSpy).toHaveBeenCalled();
expect(result).toBeInstanceOf(Array);
expect(result).toHaveLength(1);
expect(result[0]).toEqual({
type: 'transaction',
transactionData: { mockTransaction: true },
});
});
it('should handle V4UpdateLaunchpadResponse with metadata', () => {
const mockResponse = {
steps: [
createValidSolanaStep('step1', validSolanaPubkey, [
{
transaction: mockTransactionBase64,
signerPubkeys: [],
},
]),
],
metadata: {
imageUrl: 'https://example.com/updated-image.png',
metadataUrl: 'https://example.com/updated-metadata.json',
},
};
const result = transactions_1.SolanaTransactionAdapters.fromV4TransactionResponse(mockResponse);
expect(deserializeSpy).toHaveBeenCalled();
expect(result).toBeInstanceOf(Array);
expect(result).toHaveLength(1);
expect(result[0]).toEqual({
type: 'transaction',
transactionData: { mockTransaction: true },
});
});
it('should handle V4MintResponse', () => {
const mockResponse = {
steps: [
createValidSolanaStep('step1', validSolanaPubkey, [
{
transaction: mockTransactionBase64,
signerPubkeys: [],
},
]),
],
};
const result = transactions_1.SolanaTransactionAdapters.fromV4TransactionResponse(mockResponse);
expect(deserializeSpy).toHaveBeenCalled();
expect(result).toBeInstanceOf(Array);
expect(result).toHaveLength(1);
expect(result[0]).toEqual({
type: 'transaction',
transactionData: { mockTransaction: true },
});
});
it('should handle multiple transactions in a single step', () => {
const mockResponse = {
steps: [
createValidSolanaStep('step1', validSolanaPubkey, [
{
transaction: mockTransactionBase64,
signerPubkeys: [],
},
{
transaction: mockTransactionBase64,
signerPubkeys: [validSolanaPubkey, validSolanaPubkey],
},
]),
],
};
const result = transactions_1.SolanaTransactionAdapters.fromV4TransactionResponse(mockResponse);
expect(deserializeSpy).toHaveBeenCalledTimes(2);
expect(result).toBeInstanceOf(Array);
expect(result).toHaveLength(2);
expect(result[0]).toEqual({
type: 'transaction',
transactionData: { mockTransaction: true },
});
expect(result[1]).toEqual({
type: 'transaction',
transactionData: { mockTransaction: true },
});
});
it('should handle multiple steps with transactions', () => {
const mockResponse = {
steps: [
createValidSolanaStep('step1', validSolanaPubkey, [
{
transaction: mockTransactionBase64,
signerPubkeys: [],
},
]),
createValidSolanaStep('step2', validSolanaPubkey, [
{
transaction: mockTransactionBase64,
signerPubkeys: [validSolanaPubkey],
},
]),
],
};
const result = transactions_1.SolanaTransactionAdapters.fromV4TransactionResponse(mockResponse);
// Should process both steps
expect(deserializeSpy).toHaveBeenCalledTimes(2);
expect(result).toBeInstanceOf(Array);
expect(result).toHaveLength(2);
expect(result[0]).toEqual({
type: 'transaction',
transactionData: { mockTransaction: true },
});
expect(result[1]).toEqual({
type: 'transaction',
transactionData: { mockTransaction: true },
});
});
it('should throw error for empty steps array', () => {
const mockResponse = {
steps: [],
};
expect(() => {
transactions_1.SolanaTransactionAdapters.fromV4TransactionResponse(mockResponse);
}).toThrow('Invalid transaction response format, only Solana transactions are supported');
});
it('should throw error for non-Solana chain', () => {
const mockResponse = {
steps: [
{
id: 'step1',
chain: chains_1.Blockchain.ETHEREUM,
method: 'eth_sendTransaction',
params: {
from: '0x123',
to: '0x456',
value: '0x0',
data: '0x0',
},
},
],
};
expect(() => {
transactions_1.SolanaTransactionAdapters.fromV4TransactionResponse(mockResponse);
}).toThrow('Invalid transaction response format, only Solana transactions are supported');
});
it('should throw error for unsupported method', () => {
const mockResponse = {
steps: [
{
id: 'step1',
chain: chains_1.Blockchain.SOLANA,
method: 'unsupportedMethod',
params: {
feePayer: 'mockFeePayer',
transactions: [],
},
},
],
};
expect(() => {
transactions_1.SolanaTransactionAdapters.fromV4TransactionResponse(mockResponse);
}).toThrow('Invalid transaction response format, only Solana transactions are supported');
});
it('should throw error for invalid transaction data', () => {
const mockResponse = {
steps: [
createValidSolanaStep('step1', 'mockFeePayer', [
{
transaction: 'invalid-base64',
signerPubkeys: [],
},
]),
],
};
// Mock deserialize to throw an error
deserializeSpy.mockImplementation(() => {
throw new Error('Invalid transaction response format, only Solana transactions are supported');
});
expect(() => {
transactions_1.SolanaTransactionAdapters.fromV4TransactionResponse(mockResponse);
}).toThrow('Invalid transaction response format, only Solana transactions are supported');
});
});
});