Skip to content

Conversation

@r-near
Copy link
Contributor

@r-near r-near commented Nov 12, 2025

Adds ergonomic API for global contracts matching the semantics from near-sdk-rs PR #1403.

New API

Publishing contract code:

// Immutable (hash-based)
Contract::publish_contract(code)
    .as_hash()
    .with_signer("publisher.testnet".parse()?, signer)
    .send_to(&network)
    .await?;

// Mutable (account-based)
Contract::publish_contract(code)
    .as_account("nft-template.testnet".parse()?)
    .with_signer(signer)
    .send_to(&network)
    .await?;

Deploying from published code:

// Works with both hash and account ID
Contract::deploy(account)
    .deploy_from_published(code_hash)  // or account_id
    .without_init_call()
    .with_signer(signer)
    .send_to(&network)
    .await?;

Changes

  • Adds Contract::publish_contract(code) with builder pattern
    • .as_hash() for immutable deployment
    • .as_account(account_id) for mutable deployment (transaction auto-bound to account)
  • Adds DeployBuilder::deploy_from_published(reference) - unified deployment method
  • Adds IntoGlobalContractRef trait for type-safe references
  • Deprecates old 4-method API (still functional for backward compatibility)
  • Fixes global contract tests by using neard 2.9.0 (includes NEP-591 support)

Benefits

  • Clear intent: Choose .as_hash() or .as_account() at decision point
  • Correct binding: .as_account() automatically binds transaction to account
  • Impossible to misuse: No wrong method to call, no panics
  • Familiar pattern: Matches old deprecated API structure

Migration

Old methods are deprecated but still work:

  • deploy_global_contract_code().as_hash()publish_contract(code).as_hash()
  • deploy_global_contract_code().as_account_id(id)publish_contract(code).as_account(id)
  • use_global_hash(hash)deploy_from_published(hash)
  • use_global_account_id(id)deploy_from_published(id)

Adds new ergonomic methods for global contract deployment:
- Contract::publish_contract(code, account_id) - replaces 4 methods with cleaner 2-method API
- DeployBuilder::deploy_from_published(reference) - unified method accepting hash or account ID

Deprecated old methods (still functional):
- Contract::deploy_global_contract_code()
- DeployBuilder::use_global_hash()
- DeployBuilder::use_global_account_id()

Also fixes global contract tests by using neard 2.9.0 which includes NEP-591 support.

Matches semantics from near-sdk-rs PR near/near-sdk-rs#1403
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

r-near added a commit to near/near-api-js that referenced this pull request Nov 12, 2025
This PR adds a new ergonomic API for global contracts to match the
near-sdk-rs API improvements from PR #1403.

## Changes

### New API Methods
- `publishContract(code, accountId?)` - Publish contract code to global registry
  - Without accountId: Creates immutable contract (identified by code hash)
  - With accountId: Creates mutable contract (can be updated by owner)
- `deployFromPublished(reference)` - Deploy from published code
  - Accepts Uint8Array (code hash), hex string (code hash), or account ID
  - Automatically detects reference type

### Deprecated Methods
- `deployGlobalContract()` - Use `publishContract()` instead
- `useGlobalContract()` - Use `deployFromPublished()` instead

### Other Changes
- Added comprehensive tests for new API methods
- Updated cookbook example to demonstrate new API
- Old methods remain functional but marked as deprecated

## Migration Guide

**Before:**
// Deploy immutable contract
await account.deployGlobalContract(code, "codeHash");
// Deploy mutable contract
await account.deployGlobalContract(code, "accountId");
// Use by hash
await account.useGlobalContract({ codeHash });
// Use by account ID
await account.useGlobalContract({ accountId });

**After:**
// Publish immutable contract
await account.publishContract(code);
// Publish mutable contract
await account.publishContract(code, accountId);
// Deploy from hash or account ID
await account.deployFromPublished(codeHash);
await account.deployFromPublished(accountId);

Related PRs:
- near-sdk-rs: near/near-sdk-rs#1403
- near-api-rs: near/near-api-rs#84
Addresses Codex feedback - split from_signer_account() into two methods:
- from_any_account() for hash-based (None case)
- from_account() for account-based (Some case)

The from_account() method now properly binds the transaction to the
account_id provided in publish_contract(), preventing mismatches where
a different account could be passed to with_signer().

This matches the behavior of the old as_account_id() method.
Changed from confusing Option-based API to clear builder pattern:

Before:
- publish_contract(code, None).from_any_account()
- publish_contract(code, Some(id)).from_account()

After:
- publish_contract(code).as_hash()
- publish_contract(code).as_account(id)

Benefits:
- Single decision point (.as_hash vs .as_account)
- Account specified where it matters
- Impossible to misuse (no panics)
- Clearer intent
@akorchyn
Copy link
Collaborator

akorchyn commented Nov 12, 2025

I think we could also accept Vec, and it would be processed as LocalCode.

So it would be deploy_from(code)
deploy_from(account_id)
deploy_from(hash)

I'm not convinced yet on the naming side, and I would wait until we have a consensus over it.
Though I'm a fan of this Into trait

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: NEW❗

Development

Successfully merging this pull request may close these issues.

3 participants