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.0 to 0.2.1

62

lib/cjs/validateTransfer.js

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

const bignumber_js_1 = __importDefault(require("bignumber.js"));
const constants_1 = require("./constants");
/**

@@ -51,17 +52,21 @@ * Thrown when a transaction doesn't contain a valid Solana Pay transfer.

throw meta.err;
if (reference && !Array.isArray(reference)) {
reference = [reference];
}
const [preAmount, postAmount] = splToken
? yield validateSPLTokenTransfer(message, meta, recipient, splToken)
: yield validateSystemTransfer(message, meta, recipient);
? yield validateSPLTokenTransfer(message, meta, recipient, splToken, reference)
: yield validateSystemTransfer(message, meta, recipient, reference);
if (postAmount.minus(preAmount).lt(amount))
throw new ValidateTransferError('amount not transferred');
if (reference) {
if (!Array.isArray(reference)) {
reference = [reference];
}
for (const pubkey of reference) {
if (!message.accountKeys.some((accountKey) => accountKey.equals(pubkey)))
throw new ValidateTransferError('reference not found');
}
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 (!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');
}
// FIXME: add memo check
return response;

@@ -71,4 +76,19 @@ });

exports.validateTransfer = validateTransfer;
function validateSystemTransfer(message, meta, recipient) {
function validateSystemTransfer(message, meta, recipient, references) {
return __awaiter(this, void 0, void 0, function* () {
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];
web3_js_1.SystemInstruction.decodeTransfer(instruction);
// Check that the expected reference keys exactly match the extra keys provided to the instruction.
const [_from, _to, ...extraKeys] = instruction.keys;
const length = extraKeys.length;
if (length !== references.length)
throw new ValidateTransferError('invalid references');
for (let i = 0; i < length; i++) {
if (!extraKeys[i].pubkey.equals(references[i]))
throw new ValidateTransferError(`invalid reference ${i}`);
}
}
const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipient));

@@ -83,5 +103,21 @@ if (accountIndex === -1)

}
function validateSPLTokenTransfer(message, meta, recipient, splToken) {
function validateSPLTokenTransfer(message, meta, recipient, splToken, references) {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
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))
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 length = extraKeys.length;
if (length !== references.length)
throw new ValidateTransferError('invalid references');
for (let i = 0; i < length; i++) {
if (!extraKeys[i].pubkey.equals(references[i]))
throw new ValidateTransferError(`invalid reference ${i}`);
}
}
const recipientATA = yield (0, spl_token_1.getAssociatedTokenAddress)(splToken, recipient);

@@ -88,0 +124,0 @@ const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipientATA));

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

@@ -48,24 +48,25 @@ "repository": "https://github.com/solana-labs/solana-pay",

"devDependencies": {
"@types/eslint": "^8.2.1",
"@types/eslint": "^8.4.5",
"@types/eslint-plugin-prettier": "^3.1.0",
"@types/jest": "^27.4.0",
"@types/node": "^16.11.14",
"@types/prettier": "^2.4.2",
"@typescript-eslint/eslint-plugin": "^5.14.0",
"@typescript-eslint/parser": "^5.14.0",
"eslint": "^8.6.0",
"@types/jest": "^28.1.6",
"@types/node": "^18.6.2",
"@types/node-fetch": "^2.6.2",
"@types/prettier": "^2.6.4",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"eslint": "^8.20.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"gh-pages": "^3.2.3",
"jest": "^27.4.7",
"prettier": "^2.5.1",
"eslint-plugin-prettier": "^4.2.1",
"gh-pages": "^4.0.0",
"jest": "^28.1.3",
"prettier": "^2.7.1",
"shx": "^0.3.3",
"ts-jest": "^27.1.2",
"ts-node": "^10.7.0",
"ts-jest": "^28.0.7",
"ts-node": "^10.9.1",
"tsc-esm": "^1.0.4",
"tslib": "^2.3.1",
"typedoc": "^0.22.13",
"typescript": "^4.5.4",
"tslib": "^2.4.0",
"typedoc": "^0.23.9",
"typescript": "^4.7.4",
"typescript-esm": "^2.0.0"
}
}

@@ -33,4 +33,17 @@ # Solana Pay

- [Merchant Integration](https://docs.solanapay.com/core/merchant-integration)
- [Wallet Integration](https://docs.solanapay.com/core/wallet-integration)
### Transaction Requests
A Solana Pay transaction request URL describes an interactive request for any Solana transaction. The parameters in the URL are used by a wallet to make an HTTP request to compose any transaction.
- [Create a transaction request](https://docs.solanapay.com/core/transaction-request/merchant-integration)
### Transfer Requests
A Solana Pay transfer request URL describes a non-interactive request for a SOL or SPL Token transfer. The parameters in the URL are used by a wallet to directly compose the transaction.
- [Create a transfer request](https://docs.solanapay.com/core/transfer-request/merchant-integration)
- [Handle a transfer request](https://docs.solanapay.com/core/transfer-request/wallet-integration)
## Other resources
- [API Reference](https://docs.solanapay.com/api/core)

@@ -37,0 +50,0 @@ - [Brand Guidelines](https://solanapay.com/branding)

@@ -1,3 +0,8 @@

import { getAssociatedTokenAddress } from '@solana/spl-token';
import {
decodeInstruction,
getAssociatedTokenAddress,
isTransferCheckedInstruction,
isTransferInstruction,
} from '@solana/spl-token';
import {
ConfirmedTransactionMeta,

@@ -8,2 +13,4 @@ Connection,

Message,
SystemInstruction,
Transaction,
TransactionResponse,

@@ -13,3 +20,4 @@ TransactionSignature,

import BigNumber from 'bignumber.js';
import { Amount, Memo, Recipient, References, SPLToken } from './types';
import { MEMO_PROGRAM_ID } from './constants';
import { Amount, Memo, Recipient, Reference, References, SPLToken } from './types';

@@ -63,21 +71,20 @@ /**

if (reference && !Array.isArray(reference)) {
reference = [reference];
}
const [preAmount, postAmount] = splToken
? await validateSPLTokenTransfer(message, meta, recipient, splToken)
: await validateSystemTransfer(message, meta, recipient);
? await validateSPLTokenTransfer(message, meta, recipient, splToken, reference)
: await validateSystemTransfer(message, meta, recipient, reference);
if (postAmount.minus(preAmount).lt(amount)) throw new ValidateTransferError('amount not transferred');
if (reference) {
if (!Array.isArray(reference)) {
reference = [reference];
}
for (const pubkey of reference) {
if (!message.accountKeys.some((accountKey) => accountKey.equals(pubkey)))
throw new ValidateTransferError('reference not found');
}
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 (!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');
}
// FIXME: add memo check
return response;

@@ -89,4 +96,21 @@ }

meta: ConfirmedTransactionMeta,
recipient: Recipient
recipient: Recipient,
references?: Reference[]
): Promise<[BigNumber, BigNumber]> {
if (references) {
// Check that the first instruction is a system transfer instruction.
const transaction = Transaction.populate(message);
const instruction = transaction.instructions[0];
SystemInstruction.decodeTransfer(instruction);
// Check that the expected reference keys exactly match the extra keys provided to the instruction.
const [_from, _to, ...extraKeys] = instruction.keys;
const length = extraKeys.length;
if (length !== references.length) throw new ValidateTransferError('invalid references');
for (let i = 0; i < length; i++) {
if (!extraKeys[i].pubkey.equals(references[i])) throw new ValidateTransferError(`invalid reference ${i}`);
}
}
const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipient));

@@ -105,4 +129,22 @@ if (accountIndex === -1) throw new ValidateTransferError('recipient not found');

recipient: Recipient,
splToken: SPLToken
splToken: SPLToken,
references?: Reference[]
): Promise<[BigNumber, BigNumber]> {
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))
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 length = extraKeys.length;
if (length !== references.length) throw new ValidateTransferError('invalid references');
for (let i = 0; i < length; i++) {
if (!extraKeys[i].pubkey.equals(references[i])) throw new ValidateTransferError(`invalid reference ${i}`);
}
}
const recipientATA = await getAssociatedTokenAddress(splToken, recipient);

@@ -109,0 +151,0 @@ const accountIndex = message.accountKeys.findIndex((pubkey) => pubkey.equals(recipientATA));

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