Skip to content

Conversation

@joaquinsoza
Copy link
Contributor

Summary
Adds support for funding contract addresses (C...) via requestAirdrop().

Changes

  • Detect contract addresses using StrKey.isValidContract()
  • Return ContractFundingResult for contracts instead of parsing account metadata
  • Add Api.ContractFundingResult type
  • Add unit tests

Fixes #1313

  requestAirdrop() now properly supports C... (contract) addresses by
  detecting them via StrKey.isValidContract() and returning a
  ContractFundingResult instead of attempting to find a created account.

  Fixes funding contract addresses which previously threw
  'No account created in transaction' error.
@github-project-automation github-project-automation bot moved this to Backlog (Not Ready) in DevX Dec 24, 2025
@Ryang-21
Copy link
Contributor

Ryang-21 commented Jan 6, 2026

I am hesitant to have requestAirdrop return two different types. Since this will be a breaking change my thought was to just return the Api.GetTransactionResponse for both types Address Thoughts @Shaptic?

@joaquinsoza
Copy link
Contributor Author

I am hesitant to have requestAirdrop return two different types. Since this will be a breaking change my thought was to just return the Api.GetTransactionResponse for both types Address Thoughts @Shaptic?

Yeah, that makes sense! It could look something like this:

public async requestAirdrop(
  address: string | Pick<Account, "accountId">,
  friendbotUrl?: string,
): Promise<Api.GetTransactionResponse> {
  const account = typeof address === "string" ? address : address.accountId();

  friendbotUrl = friendbotUrl || (await this.getNetwork()).friendbotUrl;
  if (!friendbotUrl) {
    throw new Error("No friendbot URL configured for current network");
  }

  const response = await this.httpClient.post<FriendbotApi.Response>(
    `${friendbotUrl}?addr=${encodeURIComponent(account)}`,
  );

  // Return full transaction response for both G... and C... addresses
  return this.getTransaction(response.data.hash);
}

Usage would then be:

const tx = await server.requestAirdrop(address);
if (tx.status === Api.GetTransactionStatus.SUCCESS) {
  console.log("Funded:", tx.txHash);
}

// If user needs Account object for G... addresses:
const account = await server.getAccount(address);

This simplifies the implementation and gives users more flexibility with the full transaction details. Happy to update the PR if you'd like to go this direction.

@Ryang-21 Ryang-21 requested a review from Shaptic January 13, 2026 18:40
@Ryang-21
Copy link
Contributor

Ryang-21 commented Jan 15, 2026

Hey @joaquinsoza sorry for the delay I've thought about it some more and think it would be better to go the route of keeping requestAirdrop the same and mark it as depreciated. We can then create a new function on the rpc server called fundAddress and implement the solution you had suggested.

Would you be interested in updating the PR to reflect this direction? If not, I’m happy to take it over and implement the changes myself.

@Shaptic
Copy link
Contributor

Shaptic commented Jan 16, 2026

Yeah I’m inclined to agree with @Ryang-21 here: we don’t want to break every existing requestAirdrop user, even at a major version boundary: that’s too disruptive I think. A new method makes more sense that returns a single type, though then it becomes a challenge to create an Account object from that result, so we’d need to add that as well to minimize the impact on users.

contracts

- Add fundAddress() that supports both G... and C... addresses
- Returns GetSuccessfulTransactionResponse for consistent return type
- Mark requestAirdrop() as deprecated
- Add unit tests for fundAddress()
Copilot AI review requested due to automatic review settings January 16, 2026 22:09
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a new fundAddress() method to support funding both Stellar account (G...) and contract (C...) addresses via the Friendbot faucet. The existing requestAirdrop() method is deprecated in favor of this new method.

Changes:

  • Added new fundAddress() method that returns transaction response instead of Account object
  • Deprecated requestAirdrop() with a note directing users to the new method
  • Added comprehensive test suite for the new method covering various scenarios

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
src/rpc/server.ts Added fundAddress() method and deprecated requestAirdrop()
test/unit/server/soroban/request_airdrop.test.ts Added test suite for fundAddress() with tests for accounts, contracts, custom URLs, and error cases

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@joaquinsoza
Copy link
Contributor Author

Thanks for the feedback @Ryang-21 @Shaptic! I've updated the PR with the suggested approach:

Changes:

  • Kept requestAirdrop() unchanged and marked it as @deprecated
  • Added new fundAddress() method that:
    • Supports both G... (account) and C... (contract) addresses
    • Returns Api.GetSuccessfulTransactionResponse (single type)
    • Calls getTransaction() to get the full transaction details

Usage:

// Fund any address (account or contract)                                                       
const tx = await server.fundAddress(address);                                                   
console.log("Funded! Hash:", tx.txHash);                                                        
                                                                                                
// If you need an Account object for G... addresses:                                            
const account = await server.getAccount(address);                                               

Regarding creating an Account object from the result - I documented that users can call
server.getAccount() after funding. Let me know if you'd prefer a convenience method like
fundAndCreateAccount() that combines both steps for account addresses, or if the current
approach is sufficient.

- Add input validation for G.../C... addresses using StrKey
- Enhance error message to include transaction status on failure
- Fix test assertion to match exact error message
- Add test coverage for HTTP request failures
- Add test coverage for invalid address inputs
@github-project-automation github-project-automation bot moved this from Backlog (Not Ready) to Needs Review in DevX Jan 21, 2026
Wrap HTTP request in try-catch to provide cleaner error messages
when friendbot returns errors (e.g., when funding an already-funded address).
Copy link
Contributor

@Ryang-21 Ryang-21 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm appreciate the contribution!

@Ryang-21 Ryang-21 merged commit 6326631 into stellar:master Jan 23, 2026
10 checks passed
@github-project-automation github-project-automation bot moved this from Needs Review to Done in DevX Jan 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

requestAirdrop() throws error when funding contract addresses

3 participants