Skip to content

Conversation

@rafinskipg
Copy link
Collaborator

Adds a new transactions package to simplify transaction creation

πŸ”§ Core Features

  • βœ… Multi-chain transaction creation: Unified API for Solana, Ethereum/EVM, Bitcoin, and Sui
  • βœ… RPC configuration system: Environment variable support and runtime configuration
  • βœ… Blockchain-specific builders: Separate builders for each chain type
  • βœ… Type safety: Full TypeScript support with comprehensive interfaces

⚑ Usage Examples

  import { createSendTokenTransaction } from "@phantom/transactions";
  import { useSignAndSendTransaction, NetworkId } from "@phantom/react-sdk";

  // Native token transfer
  const { transaction, error } = await createSendTokenTransaction({
    networkId: NetworkId.SOLANA_MAINNET,
    from: "sender-address",
    to: "recipient-address",
    amount: "1.5", // 1.5 SOL
  });

  // Token transfer  
  const { transaction, error } = await createSendTokenTransaction({
    networkId: NetworkId.ETHEREUM_MAINNET,
    from: "0x...",
    to: "0x...",
    amount: "100",
    token: "0x...", // USDC contract address
    decimals: 6,
  });

  // Use with Phantom SDK
  const signature = await signAndSendTransaction({
    transaction,
    networkId,
  });

@rafinskipg rafinskipg requested a review from a team as a code owner August 1, 2025 08:19
@socket-security
Copy link

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedbitcoinjs-lib@​6.1.79910010083100
Added@​mysten/​sui.js@​0.54.19910010083100

View full report

Comment on lines +132 to +135
const transaction = {
to: params.token as `0x${string}`,
data: tokenContract.write.transfer.toString(), // This needs proper encoding
// Note: This is a simplified version. In practice, you'd need to properly encode the function call
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ERC-20 token transfer implementation has an issue with the transaction data encoding. The current approach using tokenContract.write.transfer.toString() won't produce valid transaction data that can be executed on-chain.

For proper ERC-20 transfers, the transaction data needs to be encoded with the function signature and properly formatted parameters. Consider using viem's encodeFunctionData method instead:

import { encodeFunctionData } from 'viem'

// ...

const data = encodeFunctionData({
  abi: ERC20_ABI,
  functionName: 'transfer',
  args: [params.to as `0x${string}`, value]
})

const transaction = {
  to: params.token as `0x${string}`,
  data
}

This will ensure the transaction contains properly encoded calldata that the EVM can interpret correctly when executing the token transfer.

Suggested change
const transaction = {
to: params.token as `0x${string}`,
data: tokenContract.write.transfer.toString(), // This needs proper encoding
// Note: This is a simplified version. In practice, you'd need to properly encode the function call
const transaction = {
to: params.token as `0x${string}`,
data: encodeFunctionData({
abi: ERC20_ABI,
functionName: 'transfer',
args: [params.to as `0x${string}`, value]
})
}

Spotted by Diamond

Is this helpful? React πŸ‘ or πŸ‘Ž to let us know.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +36 to +40
const amount = typeof params.amount === 'string'
? Math.floor(parseFloat(params.amount) * 1_000_000_000)
: typeof params.amount === 'bigint'
? Number(params.amount)
: Math.floor(params.amount * 1_000_000_000);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conversion from bigint to Number in the SUI amount calculation risks precision loss for large values. This is particularly problematic for cryptocurrency transactions where exact amounts are critical. Consider preserving the full precision by using bigint arithmetic throughout:

const amount = typeof params.amount === 'string'
  ? BigInt(Math.floor(parseFloat(params.amount) * 1_000_000_000))
  : typeof params.amount === 'bigint'
  ? params.amount
  : BigInt(Math.floor(params.amount * 1_000_000_000));

This approach maintains precision for large transaction amounts while still handling all the input types correctly.

Suggested change
const amount = typeof params.amount === 'string'
? Math.floor(parseFloat(params.amount) * 1_000_000_000)
: typeof params.amount === 'bigint'
? Number(params.amount)
: Math.floor(params.amount * 1_000_000_000);
const amount = typeof params.amount === 'string'
? BigInt(Math.floor(parseFloat(params.amount) * 1_000_000_000))
: typeof params.amount === 'bigint'
? params.amount
: BigInt(Math.floor(params.amount * 1_000_000_000));

Spotted by Diamond

Is this helpful? React πŸ‘ or πŸ‘Ž to let us know.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rafinskipg BigInt is probably the best stable type to use everywhere if possible? Like, just get rid of the fractional part at step 1 and stay in BigInt through everything?

import { SuiTransactionBuilderImpl } from "./builders/sui";

// Export types
export type * from "./types";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The syntax export type * from "./types"; is not valid TypeScript. TypeScript doesn't support exporting all types with the type keyword in this manner. To properly export all types and interfaces from the types file, change this to export * from "./types"; which will export both types and values.

Suggested change
export type * from "./types";
export * from "./types";

Spotted by Diamond

Is this helpful? React πŸ‘ or πŸ‘Ž to let us know.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
files: ["tsup.config.ts"],
rules: {
"import/no-extraneous-dependencies": "off",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we strictly need to be turning off this rule globally?

Comment on lines +132 to +135
const transaction = {
to: params.token as `0x${string}`,
data: tokenContract.write.transfer.toString(), // This needs proper encoding
// Note: This is a simplified version. In practice, you'd need to properly encode the function call
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import { SuiTransactionBuilderImpl } from "./builders/sui";

// Export types
export type * from "./types";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


// Convert amount to MIST (1 SUI = 1,000,000,000 MIST)
const amount = typeof params.amount === 'string'
? Math.floor(parseFloat(params.amount) * 1_000_000_000)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could make these methods generic with some baseTokenToAmount or whatever if you set up a lookup of MIST_PER_SUI / LAMPORTS_PER_SOL etc

Comment on lines +36 to +40
const amount = typeof params.amount === 'string'
? Math.floor(parseFloat(params.amount) * 1_000_000_000)
: typeof params.amount === 'bigint'
? Number(params.amount)
: Math.floor(params.amount * 1_000_000_000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rafinskipg BigInt is probably the best stable type to use everywhere if possible? Like, just get rid of the fractional part at step 1 and stay in BigInt through everything?

@rafinskipg rafinskipg marked this pull request as draft September 5, 2025 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants