Skip to content

Commit

Permalink
Withdraw payment + docs (#389)
Browse files Browse the repository at this point in the history
* add withdraw payment command + docs

add withdraw payment command + docs

* export command

* update docs with clear payee instruction
  • Loading branch information
RodrigoAD authored Sep 1, 2022
1 parent 1cce38d commit 8ca9270
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 2 deletions.
4 changes: 4 additions & 0 deletions docs/gauntlet/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Gauntlet Solana

- [Setup](./gauntlet-setup.md)
- [Withdraw Payments](./withdraw.md)
2 changes: 1 addition & 1 deletion docs/gauntlet/gauntlet-setup.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Gauntlet Solana
# Gauntlet Solana Setup

Install node version with asdf. Which can be done by running this from the base of the chainlink-solana repository:

Expand Down
19 changes: 19 additions & 0 deletions docs/gauntlet/withdraw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Withdraw Payments using Gauntlet

When Node Operators report data to a feed, they are compensated with LINK thats owned by the feed. Node operators can then withdraw the funds owed to them via gauntlet using this section below

## Sample Command Usage

Make sure to set up gauntlet using the steps described in [Gauntlet Setup](gauntlet-setup.md) before attempting to run the following command.

The `recipient` address is the payee address set in the contract configuration. This should be the Token derived address from the transaction signer address.

```bash
yarn gauntlet ocr2:withdraw_payment --network=mainnet --recipient=<PAYEE_ADDRESS> <FEED_ADDRESS>
```

If you are using a Ledger, include the `--withLedger` flag. Gauntlet will ask you to sign the transaction using your Ledger.

```bash
yarn gauntlet ocr2:withdraw_payment --network=mainnet --recipient=<PAYEE_ADDRESS> --withLedger <FEED_ADDRESS>
```
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type ProposalState = {
export const wrapCommand = (command) => {
return class Multisig extends SolanaCommand {
command: SolanaCommand
program: Program<Idl>
program: Program<any>
multisigAddress: PublicKey

static id = `${command.id}:multisig`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import ProposePayees from './proposePayees'
import FinalizeProposal from './proposal/finalizeProposal'
import Close from './close'
import WithdrawFunds from './withdrawFunds'
import WithdrawPayment from './withdrawPayment'

const getOwner = async (program, state) => {
const contractState = await program.account.state.fetch(state)
Expand Down Expand Up @@ -49,6 +50,7 @@ export default [
makeInspectOwnershipCommand(CONTRACT_LIST.OCR_2, getOwner),
makeUpgradeProgramCommand(CONTRACT_LIST.OCR_2),
WithdrawFunds,
WithdrawPayment,
// Inspection
...Inspection,
// ONLY DEV
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { Result } from '@chainlink/gauntlet-core'
import { SolanaCommand, TransactionResponse } from '@chainlink/gauntlet-solana'
import { PublicKey } from '@solana/web3.js'
import { TOKEN_PROGRAM_ID } from '@solana/spl-token'
import { utils } from '@project-serum/anchor'
import { logger, prompt } from '@chainlink/gauntlet-core/dist/utils'
import { CONTRACT_LIST, getContract } from '../../../lib/contracts'

type Input = {
recipient: string
}

export default class WithdrawPayment extends SolanaCommand {
static id = 'ocr2:withdraw_payment'
static category = CONTRACT_LIST.OCR_2

static examples = [
'yarn gauntlet ocr2:withdraw_payment --network=devnet --recipient=YOUR_LINK_ACCOUNT <AGGREGATOR_ADDR>',
'yarn gauntlet ocr2:withdraw_payment --network=devnet --recipient=FTH1Kqvr5BhiAA786DdQVBQYJ1bs5XhKwTEETKCqYwMh 9hBz81AnfoeGgqVqQHKBiAXGJ2hKAs7A2KYFxn5yGgat',
]

input: Input

makeInput = (userInput: any): Input => {
if (userInput) return userInput as Input

if (!this.flags.recipient) {
throw Error('Please specify a valid LINK --recipient for withdrawal')
}

return {
recipient: this.flags.recipient,
}
}

constructor(flags, args) {
super(flags, args)
}

buildCommand = async (flags, args) => {
const ocr2 = getContract(CONTRACT_LIST.OCR_2, '')
this.program = this.loadProgram(ocr2.idl, ocr2.programId.toString())
this.input = this.makeInput(flags.input)
return this
}

beforeExecute = async () => {
logger.loading(`Executing ${WithdrawPayment.id} from contract ${this.args[0]}`)
await prompt(`Continue?`)
}

makeRawTransaction = async (signer: PublicKey) => {
const state = new PublicKey(this.args[0])

const info = (await this.program.account.state.fetch(state)) as any
const tokenVault = new PublicKey(info.config.tokenVault)
const [vaultAuthority] = await PublicKey.findProgramAddress(
[Buffer.from(utils.bytes.utf8.encode('vault')), state.toBuffer()],
this.program.programId,
)

const data = this.program.instruction.withdrawPayment({
accounts: {
state,
authority: signer,
tokenVault: tokenVault,
vaultAuthority: vaultAuthority,
tokenProgram: TOKEN_PROGRAM_ID,
payee: new PublicKey(this.input.recipient),
},
})

return [data]
}

execute = async () => {
await this.buildCommand(this.flags, this.args)
// use local wallet as signer
const signer = this.wallet.publicKey

const rawTx = await this.makeRawTransaction(signer)
await this.simulateTx(signer, rawTx)

await this.beforeExecute()
const txhash = await this.signAndSendRawTx(rawTx)
logger.success(`Payment withdrew on tx hash: ${txhash}`)

return {
responses: [
{
tx: this.wrapResponse(txhash, this.args[0]),
contract: this.args[0],
},
],
} as Result<TransactionResponse>
}
}

0 comments on commit 8ca9270

Please sign in to comment.