Socket
Socket
Sign inDemoInstall

@solana/pay

Package Overview
Dependencies
Maintainers
14
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@solana/pay - npm Package Compare versions

Comparing version 0.2.1 to 0.2.2

6

lib/cjs/createTransfer.js

@@ -81,2 +81,3 @@ "use strict";

function createSystemInstruction(recipient, amount, sender, connection) {
var _a;
return __awaiter(this, void 0, void 0, function* () {

@@ -100,3 +101,3 @@ // Check that the sender and recipient accounts exist

// Check that the amount provided doesn't have greater precision than SOL
if (amount.decimalPlaces() > constants_1.SOL_DECIMALS)
if ((_a = amount.decimalPlaces()) !== null && _a !== void 0 ? _a : 0 > constants_1.SOL_DECIMALS)
throw new CreateTransferError('amount decimals invalid');

@@ -118,2 +119,3 @@ // Convert input decimal amount to integer lamports

function createSPLTokenInstruction(recipient, amount, splToken, sender, connection) {
var _a;
return __awaiter(this, void 0, void 0, function* () {

@@ -125,3 +127,3 @@ // Check that the token provided is an initialized mint

// Check that the amount provided doesn't have greater precision than the mint
if (amount.decimalPlaces() > mint.decimals)
if ((_a = amount.decimalPlaces()) !== null && _a !== void 0 ? _a : 0 > mint.decimals)
throw new CreateTransferError('amount decimals invalid');

@@ -128,0 +130,0 @@ // Convert input decimal amount to integer tokens according to the mint decimals

@@ -29,6 +29,7 @@ "use strict";

function encodeTransferRequestURL({ recipient, amount, splToken, reference, label, message, memo, }) {
var _a;
const pathname = recipient.toBase58();
const url = new URL(constants_1.SOLANA_PROTOCOL + pathname);
if (amount) {
url.searchParams.append('amount', amount.toFixed(amount.decimalPlaces()));
url.searchParams.append('amount', amount.toFixed((_a = amount.decimalPlaces()) !== null && _a !== void 0 ? _a : 0));
}

@@ -35,0 +36,0 @@ if (splToken) {

@@ -45,3 +45,3 @@ "use strict";

throw new ValidateTransferError('not found');
const message = response.transaction.message;
const { message, signatures } = response.transaction;
const meta = response.meta;

@@ -55,17 +55,20 @@ if (!meta)

}
// Deserialize the transaction and make a copy of the instructions we're going to mutate it.
const transaction = web3_js_1.Transaction.populate(message, signatures);
const instructions = transaction.instructions.slice();
// Transfer instruction must be the last instruction
const instruction = instructions.pop();
if (!instruction)
throw new ValidateTransferError('missing transfer instruction');
const [preAmount, postAmount] = splToken
? yield validateSPLTokenTransfer(message, meta, recipient, splToken, reference)
: yield validateSystemTransfer(message, meta, recipient, reference);
? yield validateSPLTokenTransfer(instruction, message, meta, recipient, splToken, reference)
: yield validateSystemTransfer(instruction, message, meta, recipient, reference);
if (postAmount.minus(preAmount).lt(amount))
throw new ValidateTransferError('amount not transferred');
if (memo) {
// Check that the second instruction is a memo instruction with the expected memo.
const transaction = web3_js_1.Transaction.populate(message);
const instruction = transaction.instructions[1];
if (memo !== undefined) {
// Memo instruction must be the second to last instruction
const instruction = instructions.pop();
if (!instruction)
throw new ValidateTransferError('missing memo instruction');
if (!instruction.programId.equals(constants_1.MEMO_PROGRAM_ID))
throw new ValidateTransferError('invalid memo program');
if (!instruction.data.equals(Buffer.from(memo, 'utf8')))
throw new ValidateTransferError('invalid memo');
validateMemo(instruction, memo);
}

@@ -76,8 +79,18 @@ return response;

exports.validateTransfer = validateTransfer;
function validateSystemTransfer(message, meta, recipient, references) {
function validateMemo(instruction, memo) {
// Check that the instruction is a memo instruction with no keys and the expected memo data.
if (!instruction.programId.equals(constants_1.MEMO_PROGRAM_ID))
throw new ValidateTransferError('invalid memo program');
if (instruction.keys.length)
throw new ValidateTransferError('invalid memo keys');
if (!instruction.data.equals(Buffer.from(memo, 'utf8')))
throw new ValidateTransferError('invalid memo');
}
function validateSystemTransfer(instruction, message, meta, recipient, references) {
return __awaiter(this, void 0, void 0, function* () {
const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipient));
if (accountIndex === -1)
throw new ValidateTransferError('recipient not found');
if (references) {
// Check that the first instruction is a system transfer instruction.
const transaction = web3_js_1.Transaction.populate(message);
const instruction = transaction.instructions[0];
// Check that the instruction is a system transfer instruction.
web3_js_1.SystemInstruction.decodeTransfer(instruction);

@@ -94,5 +107,2 @@ // Check that the expected reference keys exactly match the extra keys provided to the instruction.

}
const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipient));
if (accountIndex === -1)
throw new ValidateTransferError('recipient not found');
return [

@@ -104,13 +114,16 @@ new bignumber_js_1.default(meta.preBalances[accountIndex] || 0).div(web3_js_1.LAMPORTS_PER_SOL),

}
function validateSPLTokenTransfer(message, meta, recipient, splToken, references) {
function validateSPLTokenTransfer(instruction, message, meta, recipient, splToken, references) {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
const recipientATA = yield (0, spl_token_1.getAssociatedTokenAddress)(splToken, recipient);
const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipientATA));
if (accountIndex === -1)
throw new ValidateTransferError('recipient not found');
if (references) {
// Check that the first instruction is an SPL token transfer instruction.
const transaction = web3_js_1.Transaction.populate(message);
const instruction = (0, spl_token_1.decodeInstruction)(transaction.instructions[0]);
if (!(0, spl_token_1.isTransferCheckedInstruction)(instruction) && !(0, spl_token_1.isTransferInstruction)(instruction))
const decodedInstruction = (0, spl_token_1.decodeInstruction)(instruction);
if (!(0, spl_token_1.isTransferCheckedInstruction)(decodedInstruction) && !(0, spl_token_1.isTransferInstruction)(decodedInstruction))
throw new ValidateTransferError('invalid transfer');
// Check that the expected reference keys exactly match the extra keys provided to the instruction.
const extraKeys = instruction.keys.multiSigners;
const extraKeys = decodedInstruction.keys.multiSigners;
const length = extraKeys.length;

@@ -124,6 +137,2 @@ if (length !== references.length)

}
const recipientATA = yield (0, spl_token_1.getAssociatedTokenAddress)(splToken, recipient);
const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipientATA));
if (accountIndex === -1)
throw new ValidateTransferError('recipient not found');
const preBalance = (_a = meta.preTokenBalances) === null || _a === void 0 ? void 0 : _a.find((x) => x.accountIndex === accountIndex);

@@ -130,0 +139,0 @@ const postBalance = (_b = meta.postTokenBalances) === null || _b === void 0 ? void 0 : _b.find((x) => x.accountIndex === accountIndex);

{
"name": "@solana/pay",
"version": "0.2.1",
"version": "0.2.2",
"author": "Solana Maintainers <maintainers@solana.foundation>",

@@ -40,5 +40,5 @@ "repository": "https://github.com/solana-labs/solana-pay",

"@solana/qr-code-styling": "^1.6.0-beta.0",
"@solana/spl-token": "^0.2.0",
"@solana/spl-token": "^0.3.4",
"@solana/web3.js": "^1.36.0",
"bignumber.js": "^9.0.2",
"bignumber.js": "^9.1.0",
"cross-fetch": "^3.1.5",

@@ -45,0 +45,0 @@ "js-base64": "^3.7.2",

@@ -38,2 +38,3 @@ # Solana Pay

- [Create a transaction request](https://docs.solanapay.com/core/transaction-request/merchant-integration)
- [Test a transaction request URL](https://glow.app/test/solana-pay)

@@ -40,0 +41,0 @@ ### Transfer Requests

@@ -119,3 +119,3 @@ import { createTransferCheckedInstruction, getAccount, getAssociatedTokenAddress, getMint } from '@solana/spl-token';

// Check that the amount provided doesn't have greater precision than SOL
if (amount.decimalPlaces() > SOL_DECIMALS) throw new CreateTransferError('amount decimals invalid');
if (amount.decimalPlaces() ?? 0 > SOL_DECIMALS) throw new CreateTransferError('amount decimals invalid');

@@ -149,3 +149,3 @@ // Convert input decimal amount to integer lamports

// Check that the amount provided doesn't have greater precision than the mint
if (amount.decimalPlaces() > mint.decimals) throw new CreateTransferError('amount decimals invalid');
if (amount.decimalPlaces() ?? 0 > mint.decimals) throw new CreateTransferError('amount decimals invalid');

@@ -152,0 +152,0 @@ // Convert input decimal amount to integer tokens according to the mint decimals

@@ -76,3 +76,3 @@ import { SOLANA_PROTOCOL } from './constants';

if (amount) {
url.searchParams.append('amount', amount.toFixed(amount.decimalPlaces()));
url.searchParams.append('amount', amount.toFixed(amount.decimalPlaces() ?? 0));
}

@@ -79,0 +79,0 @@

@@ -15,2 +15,3 @@ import {

Transaction,
TransactionInstruction,
TransactionResponse,

@@ -65,3 +66,3 @@ TransactionSignature,

const message = response.transaction.message;
const { message, signatures } = response.transaction;
const meta = response.meta;

@@ -75,14 +76,26 @@ if (!meta) throw new ValidateTransferError('missing meta');

// Deserialize the transaction and make a copy of the instructions we're going to mutate it.
const transaction = Transaction.populate(message, signatures);
const instructions = transaction.instructions.slice();
// Transfer instruction must be the last instruction
const instruction = instructions.pop();
if (!instruction) throw new ValidateTransferError('missing transfer instruction');
const [preAmount, postAmount] = splToken
? await validateSPLTokenTransfer(message, meta, recipient, splToken, reference)
: await validateSystemTransfer(message, meta, recipient, reference);
? await validateSPLTokenTransfer(
instruction,
message,
meta,
recipient,
splToken,
reference
)
: await validateSystemTransfer(instruction, message, meta, recipient, reference);
if (postAmount.minus(preAmount).lt(amount)) throw new ValidateTransferError('amount not transferred');
if (memo) {
// Check that the second instruction is a memo instruction with the expected memo.
const transaction = Transaction.populate(message);
const instruction = transaction.instructions[1];
if (memo !== undefined) {
// Memo instruction must be the second to last instruction
const instruction = instructions.pop();
if (!instruction) throw new ValidateTransferError('missing memo instruction');
if (!instruction.programId.equals(MEMO_PROGRAM_ID)) throw new ValidateTransferError('invalid memo program');
if (!instruction.data.equals(Buffer.from(memo, 'utf8'))) throw new ValidateTransferError('invalid memo');
validateMemo(instruction, memo);
}

@@ -93,3 +106,11 @@

function validateMemo(instruction: TransactionInstruction, memo: string): void {
// Check that the instruction is a memo instruction with no keys and the expected memo data.
if (!instruction.programId.equals(MEMO_PROGRAM_ID)) throw new ValidateTransferError('invalid memo program');
if (instruction.keys.length) throw new ValidateTransferError('invalid memo keys');
if (!instruction.data.equals(Buffer.from(memo, 'utf8'))) throw new ValidateTransferError('invalid memo');
}
async function validateSystemTransfer(
instruction: TransactionInstruction,
message: Message,

@@ -100,6 +121,7 @@ meta: ConfirmedTransactionMeta,

): Promise<[BigNumber, BigNumber]> {
const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipient));
if (accountIndex === -1) throw new ValidateTransferError('recipient not found');
if (references) {
// Check that the first instruction is a system transfer instruction.
const transaction = Transaction.populate(message);
const instruction = transaction.instructions[0];
// Check that the instruction is a system transfer instruction.
SystemInstruction.decodeTransfer(instruction);

@@ -117,5 +139,2 @@

const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipient));
if (accountIndex === -1) throw new ValidateTransferError('recipient not found');
return [

@@ -128,2 +147,3 @@ new BigNumber(meta.preBalances[accountIndex] || 0).div(LAMPORTS_PER_SOL),

async function validateSPLTokenTransfer(
instruction: TransactionInstruction,
message: Message,

@@ -135,11 +155,14 @@ meta: ConfirmedTransactionMeta,

): Promise<[BigNumber, BigNumber]> {
const recipientATA = await getAssociatedTokenAddress(splToken, recipient);
const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipientATA));
if (accountIndex === -1) throw new ValidateTransferError('recipient not found');
if (references) {
// Check that the first instruction is an SPL token transfer instruction.
const transaction = Transaction.populate(message);
const instruction = decodeInstruction(transaction.instructions[0]);
if (!isTransferCheckedInstruction(instruction) && !isTransferInstruction(instruction))
const decodedInstruction = decodeInstruction(instruction);
if (!isTransferCheckedInstruction(decodedInstruction) && !isTransferInstruction(decodedInstruction))
throw new ValidateTransferError('invalid transfer');
// Check that the expected reference keys exactly match the extra keys provided to the instruction.
const extraKeys = instruction.keys.multiSigners;
const extraKeys = decodedInstruction.keys.multiSigners;
const length = extraKeys.length;

@@ -153,6 +176,2 @@ if (length !== references.length) throw new ValidateTransferError('invalid references');

const recipientATA = await getAssociatedTokenAddress(splToken, recipient);
const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipientATA));
if (accountIndex === -1) throw new ValidateTransferError('recipient not found');
const preBalance = meta.preTokenBalances?.find((x) => x.accountIndex === accountIndex);

@@ -159,0 +178,0 @@ const postBalance = meta.postTokenBalances?.find((x) => x.accountIndex === accountIndex);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc