Skip to content

Instantly share code, notes, and snippets.

@pythonpete32
Created October 18, 2023 19:58
Show Gist options
  • Save pythonpete32/d1207386373323b53427218434fce12c to your computer and use it in GitHub Desktop.
Save pythonpete32/d1207386373323b53427218434fce12c to your computer and use it in GitHub Desktop.
sign and transfer tokens from a gnosis safe with a private key signer and frame signer
// ---------------------------------------------------------------------------- //
// GNOSIS SAFE DEPLOYMENT SCRIPT //
// ---------------------------------------------------------------------------- //
import { ethers } from 'ethers'
import Safe, { EthersAdapter } from '@safe-global/protocol-kit'
import SafeApiKit from '@safe-global/api-kit'
import * as dotenv from 'dotenv'
dotenv.config()
const { log } = console
// ---------------------------------------------------------------------------- //
// create the transaction
// ---------------------------------------------------------------------------- //
// 0. variables
const DAOBOX = '0x00c71C667A4BDEbC3C9138c0709960523475B247'
const txServiceUrl = 'https://safe-transaction-base.safe.global/'
const USDC = '0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA'
const mintFunction = 'function transfer(address recipient, uint256 amount) external returns (bool)'
const BASE_RPC = "https://base-mainnet.g.alchemy.com/v2/6qDjh9sXOgcq7dKEC7bUK_8macZItN8d"
// 1. init AbuUsama.eth who will propose the tx
const provider = new ethers.providers.JsonRpcProvider(BASE_RPC)
const signer = new ethers.Wallet(process.env.PK!, provider)
log('signer address', signer.address)
const ethAdapterOwner1 = new EthersAdapter({
ethers,
signerOrProvider: signer,
})
const abuUsamaSafeSigner = await Safe.create({
ethAdapter: ethAdapterOwner1,
safeAddress: DAOBOX,
})
const usdcInterface = new ethers.utils.Interface([mintFunction])
const data = usdcInterface.encodeFunctionData('transfer', [signer.address, ethers.utils.parseUnits('900', 6).toString()])
const initialUSDCTransaction = await abuUsamaSafeSigner.createTransaction({
safeTransactionData: {
to: USDC,
value: '0',
data,
}
})
log('safeTransaction', initialUSDCTransaction)
const initialTxHash = await abuUsamaSafeSigner.getTransactionHash(initialUSDCTransaction)
const abuUsamaSignature = await abuUsamaSafeSigner.signTransactionHash(initialTxHash)
log('abuUsamaSignature', abuUsamaSignature)
log('proposing transaction')
const safeService = new SafeApiKit({ txServiceUrl, ethAdapter: ethAdapterOwner1 })
const proposalTx = await safeService.proposeTransaction({
safeAddress: DAOBOX,
safeTransactionData: initialUSDCTransaction.data,
safeTxHash: initialTxHash,
senderAddress: signer.address,
senderSignature: abuUsamaSignature.data,
})
console.log('proposalTx', proposalTx)
// ---------------------------------------------------------------------------- //
// transaction is proposed, now we need to confirm it
// ---------------------------------------------------------------------------- //
// get frame provider
const frameProvider = new ethers.providers.JsonRpcProvider({
url: 'http://127.0.0.1:1248',
headers: {
'Origin': 'http://MyCustomAppName'
},
allowInsecureAuthentication: true
});
// switch to base
await frameProvider.send('wallet_switchEthereumChain', [{ chainId: '0x2105' }])
// check network
console.log({ network: await frameProvider.getNetwork() })
// get signer
const frameSigner = frameProvider.getSigner();
const frameSignerAddress = await frameSigner.getAddress()
console.log('signer address', frameSignerAddress)
const FrameEthAdapter = new EthersAdapter({
ethers,
signerOrProvider: frameSigner,
})
const frameSafeSigner = await Safe.create({
ethAdapter: FrameEthAdapter,
safeAddress: DAOBOX,
})
const frameSafeService = new SafeApiKit({ txServiceUrl, ethAdapter: FrameEthAdapter })
const framePendingTransactions = (await frameSafeService.getPendingTransactions(DAOBOX)).results
console.log("num of transactions", framePendingTransactions.length)
const framePendingTransaction = framePendingTransactions.slice(-1)[0]
const safeTxHash = framePendingTransaction.safeTxHash
console.log('safeTxHash', safeTxHash)
// console.log('pendingTransaction', pendingTransaction)
const frameSignature = await frameSafeSigner.signTransactionHash(safeTxHash)
console.log('signature', frameSignature)
// Confirm the Safe transaction
const frameSignatureResponse = await frameSafeService.confirmTransaction(safeTxHash, frameSignature.data)
console.log('signatureResponse', frameSignatureResponse)
//----------------------------------------------------------------------------
// execute the transaction
//----------------------------------------------------------------------------
const pendingTransaction = (await safeService.getPendingTransactions(DAOBOX)).results.slice(-1)[0]
console.log('pendingTransactions', pendingTransaction)
const res = await abuUsamaSafeSigner.executeTransaction(pendingTransaction)
console.log('res', res)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment