jito-distributor-sdk
Version:
TypeScript SDK for JITO Merkle Distributor with production-ready versioning and double-hashing support
729 lines • 17.1 kB
JSON
{
"version": "0.0.1",
"name": "merkle_distributor",
"instructions": [
{
"name": "newDistributor",
"docs": [
"READ THE FOLLOWING:",
"",
"This instruction is susceptible to frontrunning that could result in loss of funds if not handled properly.",
"",
"An attack could look like:",
"- A legitimate user opens a new distributor.",
"- Someone observes the call to this instruction.",
"- They replace the clawback_receiver, admin, or time parameters with their own.",
"",
"One situation that could happen here is the attacker replaces the admin and clawback_receiver with their own",
"and sets the clawback_start_ts with the minimal time allowed. After clawback_start_ts has elapsed,",
"the attacker can steal all funds from the distributor to their own clawback_receiver account.",
"",
"HOW TO AVOID:",
"- When you call into this instruction, ensure your transaction succeeds.",
"- To be extra safe, after your transaction succeeds, read back the state of the created MerkleDistributor account and",
"assert the parameters are what you expect, most importantly the clawback_receiver and admin.",
"- If your transaction fails, double check the value on-chain matches what you expect."
],
"accounts": [
{
"name": "distributor",
"isMut": true,
"isSigner": false,
"docs": [
"[MerkleDistributor]."
],
"pda": {
"seeds": [
{
"kind": "const",
"type": "string",
"value": "MerkleDistributor"
},
{
"kind": "account",
"type": "publicKey",
"account": "Mint",
"path": "mint"
},
{
"kind": "arg",
"type": "u64",
"path": "version"
}
]
}
},
{
"name": "clawbackReceiver",
"isMut": true,
"isSigner": false,
"docs": [
"Clawback receiver token account"
]
},
{
"name": "mint",
"isMut": false,
"isSigner": false,
"docs": [
"The mint to distribute."
]
},
{
"name": "tokenVault",
"isMut": true,
"isSigner": false,
"docs": [
"Token vault"
]
},
{
"name": "admin",
"isMut": true,
"isSigner": true,
"docs": [
"Admin wallet, responsible for creating the distributor and paying for the transaction.",
"Also has the authority to set the clawback receiver and change itself."
]
},
{
"name": "systemProgram",
"isMut": false,
"isSigner": false,
"docs": [
"The [System] program."
]
},
{
"name": "associatedTokenProgram",
"isMut": false,
"isSigner": false,
"docs": [
"The [Associated Token] program."
]
},
{
"name": "tokenProgram",
"isMut": false,
"isSigner": false,
"docs": [
"The [Token] program."
]
}
],
"args": [
{
"name": "version",
"type": "u64"
},
{
"name": "root",
"type": {
"array": [
"u8",
32
]
}
},
{
"name": "maxTotalClaim",
"type": "u64"
},
{
"name": "maxNumNodes",
"type": "u64"
},
{
"name": "startVestingTs",
"type": "i64"
},
{
"name": "endVestingTs",
"type": "i64"
},
{
"name": "clawbackStartTs",
"type": "i64"
}
]
},
{
"name": "newClaim",
"accounts": [
{
"name": "distributor",
"isMut": true,
"isSigner": false,
"docs": [
"The [MerkleDistributor]."
]
},
{
"name": "claimStatus",
"isMut": true,
"isSigner": false,
"docs": [
"Claim status PDA"
],
"pda": {
"seeds": [
{
"kind": "const",
"type": "string",
"value": "ClaimStatus"
},
{
"kind": "account",
"type": "publicKey",
"path": "claimant"
},
{
"kind": "account",
"type": "publicKey",
"account": "MerkleDistributor",
"path": "distributor"
}
]
}
},
{
"name": "from",
"isMut": true,
"isSigner": false,
"docs": [
"Distributor ATA containing the tokens to distribute."
]
},
{
"name": "to",
"isMut": true,
"isSigner": false,
"docs": [
"Account to send the claimed tokens to."
]
},
{
"name": "claimant",
"isMut": true,
"isSigner": true,
"docs": [
"Who is claiming the tokens."
]
},
{
"name": "tokenProgram",
"isMut": false,
"isSigner": false,
"docs": [
"SPL [Token] program."
]
},
{
"name": "systemProgram",
"isMut": false,
"isSigner": false,
"docs": [
"The [System] program."
]
}
],
"args": [
{
"name": "amountUnlocked",
"type": "u64"
},
{
"name": "amountLocked",
"type": "u64"
},
{
"name": "proof",
"type": {
"vec": {
"array": [
"u8",
32
]
}
}
}
]
},
{
"name": "claimLocked",
"accounts": [
{
"name": "distributor",
"isMut": true,
"isSigner": false,
"docs": [
"The [MerkleDistributor]."
]
},
{
"name": "claimStatus",
"isMut": true,
"isSigner": false,
"docs": [
"Claim Status PDA"
],
"pda": {
"seeds": [
{
"kind": "const",
"type": "string",
"value": "ClaimStatus"
},
{
"kind": "account",
"type": "publicKey",
"path": "claimant"
},
{
"kind": "account",
"type": "publicKey",
"account": "MerkleDistributor",
"path": "distributor"
}
]
}
},
{
"name": "from",
"isMut": true,
"isSigner": false,
"docs": [
"Distributor ATA containing the tokens to distribute."
]
},
{
"name": "to",
"isMut": true,
"isSigner": false,
"docs": [
"Account to send the claimed tokens to.",
"Claimant must sign the transaction and can only claim on behalf of themself"
]
},
{
"name": "claimant",
"isMut": true,
"isSigner": true,
"docs": [
"Who is claiming the tokens."
]
},
{
"name": "tokenProgram",
"isMut": false,
"isSigner": false,
"docs": [
"SPL [Token] program."
]
}
],
"args": []
},
{
"name": "clawback",
"accounts": [
{
"name": "distributor",
"isMut": true,
"isSigner": false,
"docs": [
"The [MerkleDistributor]."
]
},
{
"name": "from",
"isMut": true,
"isSigner": false,
"docs": [
"Distributor ATA containing the tokens to distribute."
]
},
{
"name": "to",
"isMut": true,
"isSigner": false,
"docs": [
"The Clawback token account."
]
},
{
"name": "claimant",
"isMut": false,
"isSigner": true,
"docs": [
"Claimant account",
"Anyone can claw back the funds"
]
},
{
"name": "systemProgram",
"isMut": false,
"isSigner": false,
"docs": [
"The [System] program."
]
},
{
"name": "tokenProgram",
"isMut": false,
"isSigner": false,
"docs": [
"SPL [Token] program."
]
}
],
"args": []
},
{
"name": "setClawbackReceiver",
"accounts": [
{
"name": "distributor",
"isMut": true,
"isSigner": false,
"docs": [
"The [MerkleDistributor]."
]
},
{
"name": "newClawbackAccount",
"isMut": false,
"isSigner": false,
"docs": [
"New clawback account"
]
},
{
"name": "admin",
"isMut": true,
"isSigner": true,
"docs": [
"Admin signer"
]
}
],
"args": []
},
{
"name": "setAdmin",
"accounts": [
{
"name": "distributor",
"isMut": true,
"isSigner": false,
"docs": [
"The [MerkleDistributor]."
]
},
{
"name": "admin",
"isMut": true,
"isSigner": true,
"docs": [
"Admin signer"
]
},
{
"name": "newAdmin",
"isMut": true,
"isSigner": false,
"docs": [
"New admin account"
]
}
],
"args": []
}
],
"accounts": [
{
"name": "ClaimStatus",
"docs": [
"Holds whether or not a claimant has claimed tokens."
],
"type": {
"kind": "struct",
"fields": [
{
"name": "claimant",
"docs": [
"Authority that claimed the tokens."
],
"type": "publicKey"
},
{
"name": "lockedAmount",
"docs": [
"Locked amount"
],
"type": "u64"
},
{
"name": "lockedAmountWithdrawn",
"docs": [
"Locked amount withdrawn"
],
"type": "u64"
},
{
"name": "unlockedAmount",
"docs": [
"Unlocked amount"
],
"type": "u64"
}
]
}
},
{
"name": "MerkleDistributor",
"docs": [
"State for the account which distributes tokens."
],
"type": {
"kind": "struct",
"fields": [
{
"name": "bump",
"docs": [
"Bump seed."
],
"type": "u8"
},
{
"name": "version",
"docs": [
"Version of the airdrop"
],
"type": "u64"
},
{
"name": "root",
"docs": [
"The 256-bit merkle root."
],
"type": {
"array": [
"u8",
32
]
}
},
{
"name": "mint",
"docs": [
"[Mint] of the token to be distributed."
],
"type": "publicKey"
},
{
"name": "tokenVault",
"docs": [
"Token Address of the vault"
],
"type": "publicKey"
},
{
"name": "maxTotalClaim",
"docs": [
"Maximum number of tokens that can ever be claimed from this [MerkleDistributor]."
],
"type": "u64"
},
{
"name": "maxNumNodes",
"docs": [
"Maximum number of nodes in [MerkleDistributor]."
],
"type": "u64"
},
{
"name": "totalAmountClaimed",
"docs": [
"Total amount of tokens that have been claimed."
],
"type": "u64"
},
{
"name": "numNodesClaimed",
"docs": [
"Number of nodes that have been claimed."
],
"type": "u64"
},
{
"name": "startTs",
"docs": [
"Lockup time start (Unix Timestamp)"
],
"type": "i64"
},
{
"name": "endTs",
"docs": [
"Lockup time end (Unix Timestamp)"
],
"type": "i64"
},
{
"name": "clawbackStartTs",
"docs": [
"Clawback start (Unix Timestamp)"
],
"type": "i64"
},
{
"name": "clawbackReceiver",
"docs": [
"Clawback receiver"
],
"type": "publicKey"
},
{
"name": "admin",
"docs": [
"Admin wallet"
],
"type": "publicKey"
},
{
"name": "clawedBack",
"docs": [
"Whether or not the distributor has been clawed back"
],
"type": "bool"
}
]
}
}
],
"events": [
{
"name": "NewClaimEvent",
"fields": [
{
"name": "claimant",
"type": "publicKey",
"index": false
},
{
"name": "timestamp",
"type": "i64",
"index": false
}
]
},
{
"name": "ClaimedEvent",
"fields": [
{
"name": "claimant",
"type": "publicKey",
"index": false
},
{
"name": "amount",
"type": "u64",
"index": false
}
]
}
],
"errors": [
{
"code": 6000,
"name": "InsufficientUnlockedTokens",
"msg": "Insufficient unlocked tokens"
},
{
"code": 6001,
"name": "StartTooFarInFuture",
"msg": "Deposit Start too far in future"
},
{
"code": 6002,
"name": "InvalidProof",
"msg": "Invalid Merkle proof."
},
{
"code": 6003,
"name": "ExceededMaxClaim",
"msg": "Exceeded maximum claim amount"
},
{
"code": 6004,
"name": "MaxNodesExceeded",
"msg": "Exceeded maximum node count"
},
{
"code": 6005,
"name": "Unauthorized",
"msg": "Account is not authorized to execute this instruction"
},
{
"code": 6006,
"name": "OwnerMismatch",
"msg": "Token account owner did not match intended owner"
},
{
"code": 6007,
"name": "ClawbackDuringVesting",
"msg": "Clawback cannot be before vesting ends"
},
{
"code": 6008,
"name": "ClawbackBeforeStart",
"msg": "Attempted clawback before start"
},
{
"code": 6009,
"name": "ClawbackAlreadyClaimed",
"msg": "Clawback already claimed"
},
{
"code": 6010,
"name": "InsufficientClawbackDelay",
"msg": "Clawback start must be at least one day after vesting end"
},
{
"code": 6011,
"name": "SameClawbackReceiver",
"msg": "New and old Clawback receivers are identical"
},
{
"code": 6012,
"name": "SameAdmin",
"msg": "New and old admin are identical"
},
{
"code": 6013,
"name": "ClaimExpired",
"msg": "Claim window expired"
},
{
"code": 6014,
"name": "ArithmeticError",
"msg": "Arithmetic Error (overflow/underflow)"
},
{
"code": 6015,
"name": "StartTimestampAfterEnd",
"msg": "Start Timestamp cannot be after end Timestamp"
},
{
"code": 6016,
"name": "TimestampsNotInFuture",
"msg": "Timestamps cannot be in the past"
},
{
"code": 6017,
"name": "InvalidVersion",
"msg": "Airdrop Version Mismatch"
}
]
}