Repository navigation
Apps: wallet.createOffer, so an app's offers are Sage's own - #899
Open
awizardxch wants to merge 1 commit into
Open
awizardxch wants to merge 1 commit into
awizardxch wants to merge 1 commit into
Conversation
An app that trades through offers could only build an offer itself and ask
Sage to sign its coin spends, so Sage never recorded it: the offer was missing
from the Offers page, its coins were not reserved, and it could not be
cancelled from Sage. WalletConnect sites already get this with
chia_createOffer.
wallet.createOffer is the bridge twin of chia_createOffer: offerAssets and
requestAssets (assetId empty or omitted for XCH, else a CAT asset id, NFT id
or option id; optional hiddenPuzzleHash; amount in mojos), an optional fee
and an optional expiresAtSecond. It always asks for approval: the approval
card lists what is offered and requested (with the wallet's token names and
precision where it knows them, and the raw amounts and asset ids), the fee
and the expiry. On approval it calls make_offer with auto_import, so the
offer is listed, its coins reserved and it can be cancelled in Sage, and
returns { offer, id } as chia_createOffer does. Amounts are validated as
positive integer mojos before the approval is shown.
It is gated by wallet.sign_coin_spends, since making an offer is Sage
signing spends of its own coins after a per-request approval, and binds the
approval to the active wallet. The SDK gains wallet.createOffer.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
An app running inside Sage that trades through offers has no way to ask Sage for an offer. It can only build the offer itself and ask Sage to sign the coin spends (
wallet.signCoinSpends). Sage never records the result, so the offer:A website connected over WalletConnect does not have this problem, because
chia_createOffercallsmake_offerand the offer is imported. The app bridge has no matching method.Change
This adds a new user bridge method,
wallet.createOffer. It is the bridge twin ofchia_createOffer.Params:
offerAssetsandrequestAssetstake{ assetId?, hiddenPuzzleHash?, amount }. An empty or omittedassetIdmeans XCH. Otherwise it is a CAT asset id, NFT id or option id, asmake_offeraccepts.amountis in mojos, as a number or an integer string.fee(optional, mojos).expiresAtSecond(optional).Validation: before any approval is shown, every amount must be a positive integer number of mojos and the fee must be an integer. An empty offer is refused. Malformed requests fail without a prompt.
Approval: approval is required on every call and can never be auto-approved. The new
createOffercard in the bridge-approval system app shows:The approval is bound to the active wallet (
binds_approval_to_wallet).Execution: calls
make_offerwithauto_import: true(no receive address, automatic coin selection). The offer is listed on the Offers page, its coins are reserved, and it can be cancelled there. Returns{ offer, id }, aschia_createOfferdoes.Capability: the method is gated by the existing
wallet.sign_coin_spends. Making an offer means Sage signs spends of its own coins after a per-request approval, which is what that capability already grants.I did not add a new capability key for a compatibility reason. An unknown capability key fails manifest parsing on older Sage versions. An app that declared a new
wallet.create_offercapability could therefore not install on any Sage released before this change, even though it would fall back fine without the method. If you would prefer a dedicated capability anyway, it is a small change, and I'm happy to make it.SDK:
sage-app-sdkgainswallet.createOffer(input)and theWalletCreateOfferParams/WalletCreateOfferResulttypes (generated).Docs:
docs/generated/user-bridge-methods.mdregenerated withpnpm generate:app-docs.Unit tests in
create_offer.rscover:MakeOffer;How to test
cargo test -p sage-apps create_offercargo clippy --workspace --all-features --all-targets,cargo fmt --all -- --checkpnpm generate:types && pnpm build:packages && node builtin-apps/src/system/build.mjs bridge-approval(type-checks the approval card against the generated types), thenpnpm lintandpnpm prettier:check.In a dev build, from any installed app that has
wallet.sign_coin_spends, call:User denied the request.{ offer, id }. The offer then appears on the Offers page with its coins reserved, and Cancel works there.Call it with
{}. It fails withFailed to decode wallet.createOffer params ...and no approval is shown.🤖 Generated with Claude Code