
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
linkdrop-sdk
Advanced tools
import { LinkdropSDK } from 'linkdrop-sdk'
const baseUrl = "https://p2p.linkdrop.io" // baseUrl is the host to be used to generate claim URLs. Required
// const apiKey = "spfurjdmvfkdlfo" // apiKey is the string parameter that will be passed to headers as Bearer token ("authorization" header). Not required. Default value: null
// const apiUrl = "https://api.myurl.com" // apiUrl is the string parameter that will be used as request url prefix for endpoints. Not required. Default value: https://escrow-api.linkdrop.io/v3
const getRandomBytes = (length) => {
return new Uint8Array(crypto.randomBytes(length));
} // To avoid using and linking native crypto libraries, we ask to pass a random bytes generation function. Required
const sdk = LinkdropSDK({
baseUrl,
getRandomBytes,
// apiKey,
// apiUrl
})
1. Initialize claim link object:
Learn more about the claimLink object in the ClaimLink section
const from = "0x2331bca1f2de4661ed88a30c99a7a9449aa84195" // Sender's Ethereum address
const token = "0x6f8a06447ff6fcf75d803135a7de15ce88c1d4ec" // token contract address
const tokenType = "ERC20"
const chainId = 137 // network chain ID
const expiration = "1695985897077" // unix timestamp after which the claim link will expire and amount will be sent back to sender unless it was claimed before. Optional param, it not passed, it's going to be set to 15 days from now
const amount = "1000000" // atomic amount of tokens that sender wants to send (before fees)
const claimLink = await sdk.createClaimLink({
from,
token,
amount,
expiration,
chainId,
tokenType
})
const from = "0x2331bca1f2de4661ed88a30c99a7a9449aa84195" // Sender's Ethereum address
const token = "0x2b7ca50f95e830cd7f47f42f156a6934906e3957" // token contract address
const tokenType = "ERC721"
const chainId = 137 // network chain ID
const expiration = "1695985897077" // unix timestamp after which the claim link will expire and amount will be sent back to sender unless it was claimed before. Optional param, it not passed, it's going to be set to 15 days from now
const tokenId = '4'
const claimLink = await sdk.createClaimLink({
from,
token,
expiration,
chainId,
tokenType,
tokenId
})
const from = "0x2331bca1f2de4661ed88a30c99a7a9449aa84195" // Sender's Ethereum address
const token = "0x344ed1c4387f7f18de4655a982513e22a8034bd3" // token contract address
const tokenType = "ERC1155"
const chainId = 137 // network chain ID
const expiration = "1695985897077" // unix timestamp after which the claim link will expire and amount will be sent back to sender unless it was claimed before. Optional param, it not passed, it's going to be set to 15 days from now
const tokenId = "1"
const amount = "1"
const claimLink = await sdk.createClaimLink({
from,
token,
amount,
expiration,
chainId,
tokenType,
tokenId
})
You can update an amount for "NATIVE", "ERC20", and "ERC1155" tokens
const { amount, feeAmount, totalAmount, feeToken } = await claimLink.updateAmount(amount)
Methods createClaimLink and updateAmount will throw an error if amount is not valid according to limits.
To define the minimum and maximum limit of amount that can be sent via link, use the getLimits method. Method is not available for ERC721 or ERC1155 tokens
const token = "0x6f8a06447ff6fcf75d803135a7de15ce88c1d4ec" // token contract address. Not required if tokenType is NATIVE
const tokenType = "ERC20" // one of "NATIVE" | "ERC20" | "ERC721" | "ERC1155"
const chainId = 137 // network chain ID
const {
minTransferAmount,
maxTransferAmount,
minTransferAmountUSD,
maxTransferAmountUSD
} = await sdk.getLimits({
token,
tokenType,
chainId
})
2a. Deposit USDC tokens to escrow contract via EIP-3009 (transferWithAuthorization) :
To avoid asking for sender private key directly, we ask to pass a function that generates a EIP712 signature using Sender's private key. The function should be similar to ethers signer.signTypedData - https://docs.ethers.org/v6/api/providers/#Signer-signTypedData
const signTypedData = (domain, types, message) => signer.signTypedData(domain, types, message)
// authConfig is optional. Use it if you need to define domain and method of authorization
const authConfig = {
domain: {
// required params
name,
version,
verifyingContract,
// optional params
chainId,
salt
},
authorizationMethod // "ApproveWithAuthorization" || "ReceiveWithAuthorization"
}
const { claimUrl, transferId, hash } = await claimLink.depositWithAuthorization({
signTypedData,
authConfig
})
2b. Deposit native tokens (ETH/MATIC), ERC721, ERC1155 or ERC20 tokens to escrow contract via direct call :
To avoid asking for sender private key directly, we ask to pass a function that signs and sends Ethereum transaction. The function should be similar to ethers signer.sendTransaction - https://docs.ethers.org/v6/api/providers/#Signer-signTypedData
const sendTransaction = async ({ to, value, data }) => {
const tx = await signer.sendTransaction({ to, value, data })
return { hash: tx.hash, type: 'tx' }
}
const { claimUrl, transferId, hash } = await claimLink.deposit({ sendTransaction })
For ERC20 (except USDC tokens), ERC721, and ERC1155 you need to approve tokens so that the contract has the opportunity to send them to the recipient
For SCW transactions you need to use type: 'userOp'. Default value for the type property is 'tx'
3. Re-generate Claim URL: Sender can generate a new claim URL (if the original claim URL is lost):
const { claimUrl, transferId } = await claimLink.generateClaimUrl({ signTypedData })
// share claimUrl with receiver
This methods help to retrieve claim link details by using deposit transaction hash (or sender & transferId).
As claim URL is never stored in database, it will be null on retrieval and new claim URL can be generated with claimLink.generateClaimUrl method call.
// fetch claim link using deposit transaction hash
const claimLink = await sdk.retrieveClaimLink({ chainId, txHash })
// or by using transferId
const claimLink = await sdk.retrieveClaimLink({ chainId, transferId })
// or by user operation hashч
const claimLink = await sdk.retrieveClaimLink({ chainId, opHash })
You can also fetch information about created links
const onlyActive = true // to get only active links (have not been redeemed or refunded yet) set parameter to true
const chainId = 137
const sender = '0x2331bca1f2de4661ed88a30c99a7a9449aa84195'
const limit = 10 // parameter specifies the number of claim links in response. Not required. Default: 100
const offset = 10 // parameter is used to exclude from a response the first N claim links. Not required. Default: 0
const token = "0x0000000000000000000000000000000000000000" // the parameter defines claim links related to which token address should be found. Not required. By default, the search will be performed on all token addresses
const {
claimLinks, // claim links fetched according to search parameters
resultSet // information about fetched data (count, offset, total)
} = await sdk.getSenderHistory({
// required params:
chainId,
sender,
// optional params:
onlyActive, // whether to only get the claim links that haven't been redeemed/refunded yet
limit,
offset,
token
})
// claim link contains all needed info to render the claim page
const claimLink = await sdk.getClaimLink(claimUrl)
// const dest = "0x123..134" // ethereum address of the receiver
const txHash = await claimLink.redeem(dest)
You can also define version of the link using method getVersionFromClaimUrl
const version = sdk.getVersionFromClaimUrl(claimUrl)
Additionally you can use the getVersionFromEscrowContract method to determine the specific version of the link according to escrow contract
const escrowAddress = '0x0b962bbbf101941d0d0ec1041d01668dac36647a'
const version = sdk.getVersionFromEscrowContract(escrowAddress)
ClaimLink object contains methods and properties to facilitate both creation and redemption of the claim link. ClaimLink class has been updated over different versions of the library. Specifically, there are multiple versions of ClaimLink with different features:
To handle the different versions of ClaimLink, the retrieveClaimLink method of the SDK can return an instance of ClaimLink from any of the supported versions.
import { ClaimLink, ClaimLinkV3_11 } from 'linkdrop-sdk';
const claimLink = await sdk.retrieveClaimLink({
...
});
// Check if the ClaimLink instance is from the latest version (3.14) and can call an appropriate method
if (claimLink instanceof ClaimLink) {
// call methods for the latest version of Linkdrop SDK ClaimLink
} else if (claimLink instanceof ClaimLinkV3_11) {
// call methods for version 3.11 of Linkdrop SDK ClaimLink
}
ClaimLink.claimUrl is the URL shared with recipient. It is never stored in a remote database, so this property is going be null on retrieval. New claim URL can be generated with a claimLink.generateClaimUrl method call if needed.
'NATIVE' | 'ERC20' | ;'ERC721' | 'ERC1155')https://p2p.linkdrop.io/#/usdc?k=8uoxFBZtJZA72xHJzkdZnZoKbT15Swhn4f5z6jV8Q9U&s=JeGDRq7xAPRYhhYkXRJTXh1St97nRN2m2CQG27LzAnyEA4L4APm9GbDx6kDYEZYjmeGdJgyLpY1ap9FyPtogtG48r&i=mYfAE4p&c=137&v=1'created' | 'depositing' | 'deposited' | 'redeemed'| 'redeeming' | 'error' | 'refunded' | 'refunding' | 'cancelled')operation:
'deposit' | 'redeem' | 'refund')'pending' | 'completed' | 'error')In order to get the latest status of the claim link, use the following method:
const { status, operations } = await claimLink.getStatus()
In order to get params that will be passed to the sendTransaction method when making a deposit, you can use the public method getDepositParams
const {
value,
data,
to,
} = claimLink.getDepositParams()
You can add message before the deposit. The method will be locked after the deposit
const claimLink = await sdk.createClaimLink({
...
})
const message = 'Hello world!'
const signTypedData = (domain, types, message) => signer.signTypedData(domain, types, message)
await claimLink.addMessage({
message, // max length of message is 140
signTypedData,
// optional params. By default is set to 12. Can be modified to any number between 6 and 43
encryptionKeyLength: 12
})
import { ClaimLink } from 'linkdrop-sdk';
const claimLink = await sdk.retrieveClaimLink({
...
})
if (claimLink && claimLink instanceof ClaimLink) {
const signTypedData = (domain, types, message) => signer.signTypedData(domain, types, message)
const decryptedMessage = await claimLink.decryptSenderMessage({
signTypedData
})
console.log(decryptedMessage) // 'Hello world!'
}
try {
...
const txHash = await claimLink.redeem('')
...
} catch (err) {
console.log(err.message)
// Validation Error: Argument "dest" is not provided (argument="dest", value="")
console.log(err.error)
// DESTINATION_ADDRESS_NOT_PROVIDED
}
FAQs
```js import { LinkdropSDK } from 'linkdrop-sdk'
The npm package linkdrop-sdk receives a total of 12 weekly downloads. As such, linkdrop-sdk popularity was classified as not popular.
We found that linkdrop-sdk demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.