Skip to content

Commit ef87d0e

Browse files
CopilotCopilotfrol
authored
feat: Add construct-meta-transaction command (#562)
There was no way to explicitly construct and sign a meta-transaction (delegate action) — the only path was implicit via `meta_transaction_relayer_url` in network config. This adds `transaction construct-meta-transaction` as an explicit command, and consolidates the delegate-action decision into a single context flag so signers don't check two places. ## Key changes - **New `construct-meta-transaction` command** — same CLI structure as `construct-transaction` (sender, receiver, action chain); reuses `add_action_1`/`2`/`3`/`skip_action` entirely without duplication; outputs `ConstructTransactionContext` with `sign_as_delegate_action: true` - **`sign_as_delegate_action: bool` flag** propagated through the context chain: - `ConstructTransactionContext` → `ActionContext` (via `skip_action`) → `NetworkForTransactionArgsContext` → `TransactionContext` - Set in `NetworkForTransactionArgsContext` as `context.sign_as_delegate_action || network_config.meta_transaction_relayer_url.is_some()`, so the relayer URL config is translated into the flag — signers now check one place only - **All signers updated** (`sign_with_keychain`, `sign_with_legacy_keychain`, `sign_with_private_key`, `sign_with_seed_phrase`, `sign_with_access_key_file`, `sign_with_ledger`) to check `previous_context.sign_as_delegate_action` instead of `network_config.meta_transaction_relayer_url.is_some()` - **`submit_dao_proposal` and `sign_with_mpc`** now derive `sign_as_delegate_action` from `network_config.meta_transaction_relayer_url.is_some()`, preserving existing behavior for those flows when a relayer URL is configured - **`send` step** now returns a user-facing error instead of panicking when a `SignedDelegateAction` is produced but no `meta_transaction_relayer_url` is configured (e.g. when using `construct-meta-transaction` without a relayer), with a message guiding the user to configure the relayer URL or use `transaction send-meta-transaction` Example usage: ```sh near transaction construct-meta-transaction alice.near bob.near \ add-action transfer 1NEAR \ skip \ network-config mainnet \ sign-with-keychain display ``` <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>[Task] Add `construct-meta-transaction`</issue_title> > <issue_description>### Background > > Meta-transactions on near are basically just a transaction with a single action [`DelegateAction`](https://github.com/near/nearcore/blob/master/core/primitives/src/action/delegate.rs). > > The `DelegateAction` is basically a `SignedTransaction` with `max_block_height` which controls the expiration of the signed payload. > > near-cli-rs already has support for creating and sending Meta-transactions if the network config has `meta_transaction_relayer_url`, so currently signer implementations (e.g. [1](https://github.com/near/near-cli-rs/blob/b067abdefa0306a13395e512f5453dda4b3579d4/src/transaction_signature_options/sign_with_legacy_keychain/mod.rs#L195)) make the decision based on this config setting, but there is no way to explicitly create and sign the Delegate Action. > > ### User Story > > As a NEAR CLI user, who uses dApps that support meta-transactions and use NEAR Connect with NEAR CLI plugin, I need CLI to support construction of meta-transactions just like `construct-transaction`. > > ### Acceptance Criteria > > I would like to have a new subcommand under `transaction`, so next to `construct-transaction` we could have `construct-meta-transaction`, the `construct-transaction` implementations should be reused without copy-pasting them, and the only change that is expected is to the signers implementation that would use the context flag to make the decision whether they should construct & sign a transaction or delegate action. As for the `meta_transaction_relayer_url` config option, it should be translated into the context flag setting as well, so signers don't need to check two places for the decision. > > ### Resources & Additional Notes > > _No response_</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #561 <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: frol <304265+frol@users.noreply.github.com> Co-authored-by: Vlad Frolov <frolvlad@gmail.com>
1 parent b067abd commit ef87d0e

File tree

80 files changed

+188
-12
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+188
-12
lines changed

src/commands/account/add_key/autogenerate_new_keypair/print_keypair_to_terminal/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ impl From<PrintKeypairToTerminalContext> for crate::commands::ActionContext {
7878
on_after_sending_transaction_callback: std::sync::Arc::new(
7979
move |_outcome_view, _network_config| Ok(()),
8080
),
81+
sign_as_delegate_action: false,
8182
}
8283
}
8384
}

src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_keychain/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ impl From<SaveKeypairToKeychainContext> for crate::commands::ActionContext {
7575
on_after_sending_transaction_callback: std::sync::Arc::new(
7676
|_outcome_view, _network_config| Ok(()),
7777
),
78+
sign_as_delegate_action: false,
7879
}
7980
}
8081
}

src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_legacy_keychain/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ impl From<SaveKeypairToLegacyKeychainContext> for crate::commands::ActionContext
9797
on_after_sending_transaction_callback: std::sync::Arc::new(
9898
|_outcome_view, _network_config| Ok(()),
9999
),
100+
sign_as_delegate_action: false,
100101
}
101102
}
102103
}

src/commands/account/add_key/use_ledger/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ impl From<AddLedgerKeyActionContext> for crate::commands::ActionContext {
9090
on_after_sending_transaction_callback: std::sync::Arc::new(
9191
|_outcome_view, _network_config| Ok(()),
9292
),
93+
sign_as_delegate_action: false,
9394
}
9495
}
9596
}

src/commands/account/add_key/use_manually_provided_seed_phrase/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ impl From<AddAccessWithSeedPhraseActionContext> for crate::commands::ActionConte
7474
on_after_sending_transaction_callback: std::sync::Arc::new(
7575
|_outcome_view, _network_config| Ok(()),
7676
),
77+
sign_as_delegate_action: false,
7778
}
7879
}
7980
}

src/commands/account/add_key/use_mpc/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ impl From<MpcDeriveKeyToAddContext> for crate::commands::ActionContext {
239239
on_after_sending_transaction_callback: std::sync::Arc::new(
240240
|_outcome_view, _network_config| Ok(()),
241241
),
242+
sign_as_delegate_action: false,
242243
}
243244
}
244245
}

src/commands/account/add_key/use_public_key/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ impl From<AddAccessKeyActionContext> for crate::commands::ActionContext {
6767
on_after_sending_transaction_callback: std::sync::Arc::new(
6868
|_outcome_view, _network_config| Ok(()),
6969
),
70+
sign_as_delegate_action: false,
7071
}
7172
}
7273
}

src/commands/account/create_account/fund_myself_create_account/sign_as/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ impl From<SignerAccountIdContext> for crate::commands::ActionContext {
154154
),
155155
on_before_sending_transaction_callback: item.on_before_sending_transaction_callback,
156156
on_after_sending_transaction_callback,
157+
sign_as_delegate_action: false,
157158
}
158159
}
159160
}

src/commands/account/delete_account/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ impl From<BeneficiaryAccountContext> for crate::commands::ActionContext {
106106
on_after_sending_transaction_callback: std::sync::Arc::new(
107107
|_outcome_view, _network_config| Ok(()),
108108
),
109+
sign_as_delegate_action: false,
109110
}
110111
}
111112
}

src/commands/account/delete_key/public_keys_to_delete.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ impl From<PublicKeyListContext> for crate::commands::ActionContext {
7474
on_after_sending_transaction_callback: std::sync::Arc::new(
7575
|_outcome_view, _network_config| Ok(()),
7676
),
77+
sign_as_delegate_action: false,
7778
}
7879
}
7980
}

0 commit comments

Comments
 (0)