Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
27ebf04
Before running with prettier
CoveMB Feb 21, 2025
7c7828e
After running with prettier
CoveMB Feb 21, 2025
ce5fcd3
Add consistent-type-imports rule
CoveMB Feb 21, 2025
3cd0b59
Add lint step in ci action
CoveMB Feb 21, 2025
31f0c78
resolve prettier conflict
CoveMB Feb 21, 2025
365421b
After running with prettier
CoveMB Feb 21, 2025
cedaeaa
resolve prettier conflict
CoveMB Feb 21, 2025
98bd8af
Add lint step in ci action
CoveMB Feb 21, 2025
a9098d0
resolve prettier conflict
CoveMB Feb 21, 2025
6e9df26
resolve prettier conflict
CoveMB Feb 21, 2025
574a739
Remove .vscode directory from Git tracking
CoveMB Feb 21, 2025
c0e9002
move linter action in it's own job
CoveMB Feb 21, 2025
86c65dc
add lint note in readme
CoveMB Feb 21, 2025
a1111d3
Update .github/workflows/test.yml
CoveMB Feb 21, 2025
abbd5a4
Merge remote-tracking branch 'upstream/master'
CoveMB Feb 21, 2025
beffa34
Merge branch 'master' into master
ericglau Feb 21, 2025
d6bec2a
lint script files
CoveMB Feb 21, 2025
315b775
Merge branch 'master' of github.com:CoveMB/contracts-wizard
CoveMB Feb 21, 2025
6ed6e4f
Merge remote-tracking branch 'upstream/master'
CoveMB Feb 24, 2025
ea90cd1
Merge remote-tracking branch 'upstream/master'
CoveMB Feb 28, 2025
abf687a
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 4, 2025
426b62d
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 20, 2025
ea25cc1
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 20, 2025
0911f87
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 25, 2025
4914083
Merge remote-tracking branch 'upstream/master'
CoveMB Mar 27, 2025
5ce527f
Merge remote-tracking branch 'upstream/master'
CoveMB Apr 4, 2025
03a32fc
Merge remote-tracking branch 'upstream/master'
CoveMB Apr 7, 2025
b3c0347
Merge remote-tracking branch 'upstream/master'
CoveMB Apr 12, 2025
0a52a65
Merge remote-tracking branch 'upstream/master'
CoveMB May 13, 2025
9e74342
Merge remote-tracking branch 'upstream/master'
CoveMB May 19, 2025
d727f51
Merge remote-tracking branch 'upstream/master'
CoveMB May 21, 2025
60fb18f
Merge remote-tracking branch 'upstream/master'
CoveMB May 26, 2025
cbb7631
Merge remote-tracking branch 'upstream/master'
CoveMB May 27, 2025
0f1267f
Merge remote-tracking branch 'upstream/master'
CoveMB Jun 5, 2025
acc5e6e
Merge remote-tracking branch 'upstream/master'
CoveMB Jun 16, 2025
e3b74c8
Merge remote-tracking branch 'upstream/master'
CoveMB Jun 17, 2025
16ba867
Merge remote-tracking branch 'upstream/master'
CoveMB Jun 26, 2025
10442ac
Merge remote-tracking branch 'upstream/master'
CoveMB Jun 27, 2025
f3d5bea
Merge remote-tracking branch 'upstream/master'
CoveMB Jul 7, 2025
4427128
Merge remote-tracking branch 'upstream/master'
CoveMB Jul 10, 2025
e4734df
Merge remote-tracking branch 'upstream/master'
CoveMB Jul 24, 2025
52bd1e0
Merge remote-tracking branch 'upstream/master'
CoveMB Jul 28, 2025
0de594f
Merge branch 'master' of github.com:CoveMB/contracts-wizard
CoveMB Jul 28, 2025
5bac310
Merge remote-tracking branch 'upstream/master'
CoveMB Jul 30, 2025
63a50d5
Merge remote-tracking branch 'upstream/master'
CoveMB Aug 5, 2025
a10f142
Merge remote-tracking branch 'upstream/master'
CoveMB Aug 20, 2025
8a4840e
Merge remote-tracking branch 'upstream/master'
CoveMB Sep 12, 2025
c8bc5cf
Merge remote-tracking branch 'upstream/master'
CoveMB Sep 24, 2025
46ed7c0
Merge remote-tracking branch 'upstream/master'
CoveMB Sep 25, 2025
f721825
Merge remote-tracking branch 'upstream/master'
CoveMB Oct 20, 2025
d4003bf
Merge remote-tracking branch 'upstream/master'
CoveMB Nov 10, 2025
3ace710
Add setting for contract URI for stellar nonnfungible token
CoveMB Nov 10, 2025
164effa
add changeset
CoveMB Nov 10, 2025
26aacf1
Add protocol prefix
CoveMB Nov 10, 2025
15d8add
Update .changeset/brown-walls-roll.md
CoveMB Nov 10, 2025
3030310
Merge branch 'master' into stellar-token-uri
CoveMB Nov 11, 2025
4df51d8
Merge branch 'master' into stellar-token-uri
CoveMB Nov 12, 2025
b1fefba
Update snapshot
CoveMB Nov 12, 2025
82c2c05
Merge branch 'stellar-token-uri' of github.com:CoveMB/contracts-wizar…
CoveMB Nov 12, 2025
df68c87
Merge branch 'master' into stellar-token-uri
CoveMB Nov 12, 2025
70d400e
Merge branch 'master' into stellar-token-uri
CoveMB Nov 12, 2025
311704e
Merge branch 'master' into stellar-token-uri
CoveMB Nov 13, 2025
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
7 changes: 7 additions & 0 deletions .changeset/brown-walls-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@openzeppelin/wizard-stellar': patch
'@openzeppelin/wizard-common': patch
'@openzeppelin/contracts-mcp': patch
---

Add tokenUri setting for stellar non fungible model
1 change: 1 addition & 0 deletions packages/common/src/ai/descriptions/stellar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const stellarNonFungibleDescriptions = {
enumerable: 'Whether the NFTs are enumerable (can be iterated over).',
consecutive: 'To batch mint NFTs instead of minting them individually (sequential minting is mandatory).',
sequential: 'Whether the IDs of the minted NFTs will be sequential.',
tokenUri: 'The metadata URI returned by the token contract for every NFT.',
};

export const stellarStablecoinDescriptions = {
Expand Down
1 change: 1 addition & 0 deletions packages/core/stellar/src/generate/non-fungible.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const booleans = [true, false];
const blueprint = {
name: ['MyToken'],
symbol: ['MTK'],
tokenUri: ['https://www.mytoken.com'],
burnable: booleans,
pausable: booleans,
upgradeable: booleans,
Expand Down
4 changes: 4 additions & 0 deletions packages/core/stellar/src/non-fungible.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ testNonFungible('non-fungible - complex name', {
pausable: true,
});

testNonFungible('non-fungible custom token uri', {
tokenUri: 'https://example.com/nfts/',
});

testAPIEquivalence('non-fungible API default');

testAPIEquivalence('non-fungible API basic', { name: 'CustomToken', symbol: 'CTK' });
Expand Down
61 changes: 47 additions & 14 deletions packages/core/stellar/src/non-fungible.test.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -55,7 +55,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -98,7 +98,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env, owner: Address) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -168,7 +168,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env, owner: Address) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -254,7 +254,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env, owner: Address) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -303,7 +303,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -347,7 +347,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env, owner: Address) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -405,7 +405,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env, owner: Address) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -467,7 +467,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env, owner: Address) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -553,7 +553,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env, owner: Address) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -647,7 +647,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -683,7 +683,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env, owner: Address) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -739,7 +739,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env, owner: Address) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -842,7 +842,7 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl CustomToken {␊
pub fn __constructor(e: &Env, owner: Address) {␊
let uri = String::from_str(e, "www.mytoken.com");␊
let uri = String::from_str(e, "https://www.mytoken.com");␊
let name = String::from_str(e, "Custom $ Token");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
Expand Down Expand Up @@ -908,3 +908,36 @@ Generated by [AVA](https://avajs.dev).
#[contractimpl]␊
impl Ownable for CustomToken {}␊
`

## non-fungible custom token uri

> Snapshot 1

`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Stellar Soroban Contracts ^0.4.1␊
#![no_std]␊
use soroban_sdk::{contract, contractimpl, Env, String};␊
use stellar_macros::default_impl;␊
use stellar_tokens::non_fungible::{Base, NonFungibleToken};␊
#[contract]␊
pub struct MyToken;␊
#[contractimpl]␊
impl MyToken {␊
pub fn __constructor(e: &Env) {␊
let uri = String::from_str(e, "https://example.com/nfts/");␊
let name = String::from_str(e, "MyToken");␊
let symbol = String::from_str(e, "MTK");␊
Base::set_metadata(e, uri, name, symbol);␊
}␊
}␊
#[default_impl]␊
#[contractimpl]␊
impl NonFungibleToken for MyToken {␊
type ContractType = Base;␊
}␊
`
Binary file modified packages/core/stellar/src/non-fungible.test.ts.snap
Binary file not shown.
9 changes: 6 additions & 3 deletions packages/core/stellar/src/non-fungible.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { toByteArray } from './utils/convert-strings';
export const defaults: Required<NonFungibleOptions> = {
name: 'MyToken',
symbol: 'MTK',
tokenUri: 'https://www.mytoken.com',
burnable: false,
enumerable: false,
consecutive: false,
Expand All @@ -34,6 +35,7 @@ export function printNonFungible(opts: NonFungibleOptions = defaults): string {
export interface NonFungibleOptions extends CommonContractOptions {
name: string;
symbol: string;
tokenUri?: string;
burnable?: boolean;
enumerable?: boolean;
consecutive?: boolean;
Expand All @@ -47,6 +49,7 @@ function withDefaults(opts: NonFungibleOptions): Required<NonFungibleOptions> {
return {
...opts,
...withCommonContractDefaults(opts),
tokenUri: opts.tokenUri ?? defaults.tokenUri,
burnable: opts.burnable ?? defaults.burnable,
consecutive: opts.consecutive ?? defaults.consecutive,
enumerable: opts.enumerable ?? defaults.enumerable,
Expand Down Expand Up @@ -87,7 +90,7 @@ export function buildNonFungible(opts: NonFungibleOptions): Contract {
throw new OptionsError(errors);
}

addBase(c, toByteArray(allOpts.name), toByteArray(allOpts.symbol), allOpts.pausable);
addBase(c, toByteArray(allOpts.name), toByteArray(allOpts.symbol), toByteArray(allOpts.tokenUri), allOpts.pausable);

if (allOpts.pausable) {
addPausable(c, allOpts.access);
Expand Down Expand Up @@ -119,9 +122,9 @@ export function buildNonFungible(opts: NonFungibleOptions): Contract {
return c;
}

function addBase(c: ContractBuilder, name: string, symbol: string, pausable: boolean) {
function addBase(c: ContractBuilder, name: string, symbol: string, tokenUri: string, pausable: boolean) {
// Set metadata
c.addConstructorCode('let uri = String::from_str(e, "www.mytoken.com");');
c.addConstructorCode(`let uri = String::from_str(e, "${tokenUri}");`);
c.addConstructorCode(`let name = String::from_str(e, "${name}");`);
c.addConstructorCode(`let symbol = String::from_str(e, "${symbol}");`);
c.addConstructorCode(`Base::set_metadata(e, uri, name, symbol);`);
Expand Down
1 change: 1 addition & 0 deletions packages/mcp/src/stellar/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const stablecoinSchema = {
export const nonFungibleSchema = {
name: z.string().describe(commonDescriptions.name),
symbol: z.string().describe(commonDescriptions.symbol),
tokenUri: z.string().optional().describe(stellarNonFungibleDescriptions.tokenUri),
burnable: z.boolean().optional().describe(commonDescriptions.burnable),
enumerable: z.boolean().optional().describe(stellarNonFungibleDescriptions.enumerable),
consecutive: z.boolean().optional().describe(stellarNonFungibleDescriptions.consecutive),
Expand Down
2 changes: 2 additions & 0 deletions packages/mcp/src/stellar/tools/non-fungible.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ test('basic', async t => {
const params: z.infer<typeof t.context.schema> = {
name: 'TestToken',
symbol: 'TST',
tokenUri: 'https://example.com/nft/',
};
await assertAPIEquivalence(t, params, nonFungible.print);
});
Expand All @@ -42,6 +43,7 @@ test('all', async t => {
const params: DeepRequired<z.infer<typeof t.context.schema>> = {
name: 'TestToken',
symbol: 'TST',
tokenUri: 'https://example.com/nft/',
burnable: true,
enumerable: true,
consecutive: true,
Expand Down
15 changes: 14 additions & 1 deletion packages/mcp/src/stellar/tools/non-fungible.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,23 @@ export function registerStellarNonFungible(server: McpServer): RegisteredTool {
'stellar-non-fungible',
makeDetailedPrompt(stellarPrompts.NonFungible),
nonFungibleSchema,
async ({ name, symbol, burnable, enumerable, consecutive, pausable, mintable, sequential, upgradeable, info }) => {
async ({
name,
symbol,
tokenUri,
burnable,
enumerable,
consecutive,
pausable,
mintable,
sequential,
upgradeable,
info,
}) => {
const opts: NonFungibleOptions = {
name,
symbol,
tokenUri,
burnable,
enumerable,
consecutive,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ export const stellarNonFungibleAIFunctionDefinition = {
type: 'boolean',
description: stellarNonFungibleDescriptions.sequential,
},
tokenUri: {
type: 'string',
description: stellarNonFungibleDescriptions.tokenUri,
},
upgradeable: {
type: 'boolean',
description: stellarCommonDescriptions.upgradeable,
Expand Down
8 changes: 8 additions & 0 deletions packages/ui/src/stellar/NonFungibleControls.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@
<input bind:value={opts.symbol} use:error={errors?.symbol} />
</label>
</div>

<label class="labeled-input">
<span class="flex justify-between pr-2">
Token URI
<HelpTooltip>Sets the metadata URI that the contract returns from <code>token_uri</code>.</HelpTooltip>
</span>
<input bind:value={opts.tokenUri} placeholder="https://..." use:error={errors?.tokenUri} />
</label>
</section>

<section class="controls-section">
Expand Down
Loading