Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/node-contract-deploy-example/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
OMS_PUBLIC_API_KEY=your-public-api-key
OMS_PROJECT_ID=your-oms-project-id
# DEPLOY_SALT=0x0000000000000000000000000000000000000000000000000000000000000001
50 changes: 50 additions & 0 deletions examples/node-contract-deploy-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Node Contract Deploy Example

This example signs in with an OMS wallet, compiles a small Solidity ERC-20 with
a public `mint(address,uint256)` function, and submits a Polygon Amoy
deployment transaction through a deployer contract.

The SDK wallet transaction API requires a `to` address, so this example uses the
ERC-2470 SingletonFactory rather than a direct EVM contract-creation transaction.
The factory uses CREATE2 at `0xce0042B868300000d44A59004Da54A005ffdcf9f`
and exposes:

```solidity
function deploy(bytes initCode, bytes32 salt) external returns (address payable createdContract);
```

The script computes the contract address from the factory address, `DEPLOY_SALT`,
and the encoded init code before sending the transaction. You can override the
factory with `DEPLOYER_ADDRESS`, but the default works for Polygon Amoy.

## Tooling Choice

Use `solc` for this example's contract compilation and `viem` for deployment
calldata encoding. This keeps the example small and Node-native. Hardhat or
Foundry would be better once this grows into a larger contract project with
tests, scripts, and multiple contracts.

## Run

From the repository root:

```bash
pnpm install
pnpm build
cp examples/node-contract-deploy-example/.env.example examples/node-contract-deploy-example/.env.local
# Fill OMS_PUBLIC_API_KEY and OMS_PROJECT_ID in .env.local
pnpm dev:node-contract-deploy-example
```

The script prompts for token name, symbol, and decimals after login. The default
answers are `WalletKit Dollar`, `WKUSD`, and `6`.

Optionally set a deterministic CREATE2 salt:

```bash
DEPLOY_SALT=0x0000000000000000000000000000000000000000000000000000000000000001
```

Each deploy writes a timestamped text record under `artifacts/` with the token
metadata, computed contract address, transaction id, transaction hash, and
explorer links. Generated artifact files are ignored by git.
2 changes: 2 additions & 0 deletions examples/node-contract-deploy-example/artifacts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract PublicMintERC20 {
string public name;
string public symbol;
uint8 public immutable decimals;
uint256 public totalSupply;

mapping(address account => uint256) public balanceOf;
mapping(address owner => mapping(address spender => uint256)) public allowance;

event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);

constructor(string memory name_, string memory symbol_, uint8 decimals_) {
name = name_;
symbol = symbol_;
decimals = decimals_;
}

function mint(address to, uint256 amount) external returns (bool) {
require(to != address(0), "ERC20: mint to zero address");

totalSupply += amount;
balanceOf[to] += amount;

emit Transfer(address(0), to, amount);
return true;
}

function approve(address spender, uint256 amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}

function transfer(address to, uint256 amount) external returns (bool) {
_transfer(msg.sender, to, amount);
return true;
}

function transferFrom(address from, address to, uint256 amount) external returns (bool) {
uint256 allowed = allowance[from][msg.sender];
require(allowed >= amount, "ERC20: insufficient allowance");

if (allowed != type(uint256).max) {
allowance[from][msg.sender] = allowed - amount;
emit Approval(from, msg.sender, allowance[from][msg.sender]);
}

_transfer(from, to, amount);
return true;
}

function _transfer(address from, address to, uint256 amount) internal {
require(to != address(0), "ERC20: transfer to zero address");

uint256 balance = balanceOf[from];
require(balance >= amount, "ERC20: insufficient balance");

balanceOf[from] = balance - amount;
balanceOf[to] += amount;

emit Transfer(from, to, amount);
}
}
Loading
Loading