From 00cd6aec8f6a8c8baa1eb29ad929054b32491733 Mon Sep 17 00:00:00 2001 From: Ikenna Omekam Date: Thu, 9 Nov 2023 20:05:13 -0500 Subject: [PATCH] feature: add sender options (#8506) --- packages/pegasus/src/courier.js | 3 ++- packages/pegasus/src/ics20.js | 11 ++++++----- packages/pegasus/src/pegasus.js | 5 +++-- packages/pegasus/src/types.js | 8 +++++++- packages/pegasus/test/test-peg.js | 3 ++- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/pegasus/src/courier.js b/packages/pegasus/src/courier.js index af5b8eb5702..dc15c4d4aad 100644 --- a/packages/pegasus/src/courier.js +++ b/packages/pegasus/src/courier.js @@ -56,7 +56,7 @@ export const makeCourierMaker = transferProtocol, }) => { /** @type {Sender} */ - const send = async (zcfSeat, depositAddress, memo) => { + const send = async (zcfSeat, depositAddress, memo, opts) => { const tryToSend = async () => { const amount = zcfSeat.getAmountAllocated('Transfer', localBrand); const transferPacket = await E(transferProtocol).makeTransferPacket({ @@ -64,6 +64,7 @@ export const makeCourierMaker = remoteDenom: sendDenom, depositAddress, memo, + opts, }); // Retain the payment. We must not proceed on failure. diff --git a/packages/pegasus/src/ics20.js b/packages/pegasus/src/ics20.js index f610d6b0bbf..df96c2d8f4c 100644 --- a/packages/pegasus/src/ics20.js +++ b/packages/pegasus/src/ics20.js @@ -17,9 +17,8 @@ import { assert, details as X, Fail } from '@agoric/assert'; const ICS20_TRANSFER_SUCCESS_RESULT = 'AQ=='; // ibc-go as late as v3 requires the `sender` to be nonempty, but doesn't -// actually use it on the receiving side. We don't need it on the sending side, -// either, so we can just omit it. -export const DUMMY_SENDER_ADDRESS = 'pegasus'; +// actually use it on the receiving side. +export const DEFAULT_SENDER_ADDRESS = 'pegasus'; /** * @param {string} s @@ -51,7 +50,7 @@ const safeJSONParseObject = s => { */ export const parseICS20TransferPacket = async packet => { const ics20Packet = safeJSONParseObject(packet); - const { amount, denom, receiver, memo } = ics20Packet; + const { amount, denom, receiver, memo, opts } = ics20Packet; assert.typeof(denom, 'string', X`Denom ${denom} must be a string`); assert.typeof(receiver, 'string', X`Receiver ${receiver} must be a string`); @@ -74,6 +73,7 @@ export const parseICS20TransferPacket = async packet => { remoteDenom: denom, value, memo, + opts, }); }; @@ -89,6 +89,7 @@ export const makeICS20TransferPacket = async ({ remoteDenom, depositAddress, memo, + opts: { sender = DEFAULT_SENDER_ADDRESS }, }) => { // We're using Nat as a dynamic check for overflow. const stringValue = String(Nat(value)); @@ -99,7 +100,7 @@ export const makeICS20TransferPacket = async ({ amount: stringValue, denom: remoteDenom, receiver: depositAddress, - sender: DUMMY_SENDER_ADDRESS, + sender, memo, }; diff --git a/packages/pegasus/src/pegasus.js b/packages/pegasus/src/pegasus.js index 0ae510edcbd..9fcc7a27fe8 100644 --- a/packages/pegasus/src/pegasus.js +++ b/packages/pegasus/src/pegasus.js @@ -457,9 +457,10 @@ const makePegasus = (zcf, board, namesByAddress) => { * @param {ERef} pegP the peg over which to transfer * @param {DepositAddress} depositAddress the remote receiver's address * @param {string} [memo] the memo to attach to ics transfer packet + * @param {SenderOptions} [opts] additional sender options * @returns {Promise} to transfer, make an offer of { give: { Transfer: pegAmount } } to this invitation */ - async makeInvitationToTransfer(pegP, depositAddress, memo = '') { + async makeInvitationToTransfer(pegP, depositAddress, memo = '', opts = {}) { // Verify the peg. const peg = await pegP; const denomState = pegToDenomState.get(peg); @@ -481,7 +482,7 @@ const makePegasus = (zcf, board, namesByAddress) => { */ const offerHandler = zcfSeat => { assertProposalShape(zcfSeat, TRANSFER_PROPOSAL_SHAPE); - send(zcfSeat, depositAddress, memo); + send(zcfSeat, depositAddress, memo, opts); }; return zcf.makeInvitation(offerHandler, `pegasus ${sendDenom} transfer`); diff --git a/packages/pegasus/src/types.js b/packages/pegasus/src/types.js index d76309ef604..a315765c14e 100644 --- a/packages/pegasus/src/types.js +++ b/packages/pegasus/src/types.js @@ -13,6 +13,7 @@ * @property {Denom} remoteDenom * @property {DepositAddress} depositAddress * @property {string} memo + * @property {SenderOptions} opts */ /** @@ -47,7 +48,7 @@ */ /** - * @typedef {(zcfSeat: ZCFSeat, depositAddress: DepositAddress, memo: string) => Promise} Sender + * @typedef {(zcfSeat: ZCFSeat, depositAddress: DepositAddress, memo: string, opt: SenderOptions) => Promise} Sender * Successive transfers are not guaranteed to be processed in the order in which they were sent. * @typedef {(parts: PacketParts) => Promise} Receiver * @typedef {object} Courier @@ -111,3 +112,8 @@ * @property {ConnectionHandler} handler * @property {Subscription} subscription */ + +/** + * @typedef {object} SenderOptions + * @property {string} [sender] the sender address attached to the packet to receive any refund + */ diff --git a/packages/pegasus/test/test-peg.js b/packages/pegasus/test/test-peg.js index bf8fcccfd82..dfb86e70fbd 100644 --- a/packages/pegasus/test/test-peg.js +++ b/packages/pegasus/test/test-peg.js @@ -104,7 +104,7 @@ async function testRemotePeg(t) { denom: 'portdef/chanabc/uatom', memo: 'I am a memo!', receiver: 'markaccount', - sender: 'pegasus', + sender: 'agoric1jmd7lwdyykrxm5h83nlhg74fctwnky04ufpqtc', }, 'expected transfer packet', ); @@ -247,6 +247,7 @@ async function testRemotePeg(t) { pegP, 'markaccount', 'I am a memo!', + { sender: 'agoric1jmd7lwdyykrxm5h83nlhg74fctwnky04ufpqtc' }, ); const seat = await E(zoe).offer( transferInvitation,