feat(nodejs-server-wallets): Dynamic native gas sponsorship, Solana support, idempotent transfers - #71
Open
emtesenair wants to merge 2 commits into
Open
Conversation
…upport, idempotent transfers
Replace ZeroDev/Pimlico with Dynamic's native gas sponsorship, and restructure the
example around two chains.
Gas sponsorship:
- EVM: EIP-7702 delegation to Dynamic's UGD contract plus an EIP-712
AuthorizedExecutions intent, relayed by Dynamic. No bundler, paymaster, or smart
account.
- SVM: fee-payer replacement. Sponsorship must precede signing, since swapping the
fee payer changes the message, and your server broadcasts rather than a relayer.
Server wallets use signTransaction({ sponsor: true }), which returns the sponsored,
signed transaction in one call. Delegated wallets split it, since they hold no
caller-side key shares.
- Delegated wallets on both chains, including a sign-here/relay-there split.
Solana support:
- New src/svm/ mirroring src/evm/: wallet, sign-message, send-transaction, and
delegated variants.
- Chain-specific library code split as lib/<feature>/<chain>.ts. EVM and SVM modules
never import each other; unsuffixed lib modules are chain-agnostic.
Idempotent transfers:
- lib/transfer/ presents one call shape for either chain, native asset or token,
server or delegated signer, and selects the right retry mechanism underneath.
- src/examples/idempotency/ shows each chain's mechanism in isolation.
- IDEMPOTENCY.md documents both with measurements.
The two chains need opposite handling, which is the main thing this documents. EVM
derives the intent nonce from a business key, and the delegate contract's unordered
bitmap admits it exactly once per wallet. On SVM the transaction id is
signatures[0] — the fee payer's, which under sponsorship is Dynamic's sponsor — so
re-signing the wallet's signature is deduped, and it is rebuilding with a fresh
blockhash that produces a second executable transaction. The safe retry unit there is
the signed bytes: sign once, persist, rebroadcast verbatim.
Also:
- Bump @dynamic-labs-wallet/{node,node-evm,node-svm} to 1.0.105; drop unused deps;
pin all versions exactly.
- Add `pnpm smoke`: a tiered runner (offline / signing / onchain) over the real CLI
entrypoints, so the expensive tiers are opt-in.
- Add per-directory READMEs and a root project tree.
|
Deployment failed for project sidebar-example with the following error: |
|
Deployment failed for project dynamic-morpho with the following error: |
|
Deployment failed for project dynamic-gasless-starter with the following error: |
|
Deployment failed for project lifi with the following error: |
|
Deployment failed for project dynamic-aave with the following error: |
|
Deployment failed for project blindpay with the following error: |
|
Deployment failed for project circle-gateway with the following error: |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…quire RPC_URL
Replaces the hand-rolled EIP-712 sponsorship intent with the SDK's first-class
delegated gasless API (1.0.106+) and upgrades the Dynamic packages to 1.0.109.
- Delegated EVM sponsorship now goes through delegatedSendSponsoredTransaction /
delegatedSignSponsoredTransaction instead of assembling AuthorizedExecutions,
resolving a relayer, and signing typed data by hand. Drops ~130 lines from
src/lib/gasless/evm.ts.
- Delegated SVM sponsorship uses delegatedSignTransaction({ sponsor: true }),
folding the separate sponsorTransaction call into one request.
- userId is plumbed through the delegated credentials and required at the gasless
boundaries, where a sponsored transaction has to be attributed to the wallet's
owner. Documented in both wallet.json templates and delegated READMEs.
- Adds an autoDelegate option. It defaults to on, and is the only reason the EVM
path needs an RPC: an eth_getCode delegation check plus the EOA nonce that a
7702 authorization commits to. Resolved lazily so --pre-sign, which turns it
off, runs with no RPC_URL at all.
- RPC_URL is now required for EVM operations with no public fallback. The public
Base Sepolia endpoint is rate limited and intermittently down, which made a
correct setup look broken.
- Removes an unused client from the SVM delegated send and a duplicated SvmClient
type alias.
Docs swept for the migration: the delegated READMEs described the hand-rolled
architecture and claimed no first-class API existed, and the README listed
RPC_URL as optional. Also documents --pre-sign and the Solana devnet funding step.
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.
Replaces ZeroDev/Pimlico with Dynamic's native gas sponsorship, adds Solana
alongside EVM, and adds retry-safe (idempotent) transfers.
Gas sponsorship
AuthorizedExecutionsintent, relayed by Dynamic. No bundler, paymaster, orsmart account.
fee payer changes the message), and your server broadcasts rather than a relayer.
needs the delegated credentials, relaying needs only the environment API token.
Structure
src/evm/andsrc/svm/mirror each other. Chain-specific library code islib/<feature>/<chain>.tsand the two chains never import each other; unsuffixedlib/modules are chain-agnostic. Chain dispatch uses exhaustiveness-checkedswitches, so adding a chain fails the build at every site that needs work.
Idempotency
lib/transfer/presents one call shape for either chain — native or token, serveror delegated signer — and picks the right retry mechanism underneath.
src/examples/idempotency/shows each mechanism in isolation.IDEMPOTENCY.mddocuments both with measurements.
The two chains need opposite handling, and this is the part worth reviewing.
EVM derives the intent nonce from a business key, and the delegate contract's
unordered bitmap admits it exactly once per wallet. On SVM the transaction id is
signatures[0]— the fee payer's, which under sponsorship is Dynamic's sponsor —so re-signing the wallet's signature is deduped by Solana, and it is rebuilding
with a fresh blockhash that yields a second executable transaction. The safe retry
unit there is the signed bytes: sign once, persist, rebroadcast verbatim.
Try it
Requires EVM/SVM Gas Sponsorship enabled for the environment.
Also
@dynamic-labs-wallet/{node,node-evm,node-svm}→ 1.0.105; unused deps dropped;all versions pinned exactly.
pnpm smoke— tiered runner (offline / signing / onchain) over the real CLIentrypoints, so expensive tiers are opt-in.