Skip to content

Commit 4af98f3

Browse files
authored
Merge pull request #46 from Ndanusa/issue-19-metadata-update
Metadata Update
2 parents eb156fa + c58c93c commit 4af98f3

4 files changed

Lines changed: 109 additions & 2 deletions

File tree

contracts/token/src/events.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! Structured event emission for all token contract operations.
44
//! Events are emitted to the ledger for indexing by off-chain services.
55
6-
use soroban_sdk::{symbol_short, Address, Env, String};
6+
use soroban_sdk::{symbol_short, Address, BytesN, Env, String};
77

88
/// Emitted when the token contract is initialized.
99
pub fn emit_initialized(env: &Env, admin: &Address, decimals: u32, name: &String, symbol: &String) {
@@ -90,3 +90,27 @@ pub fn emit_unpaused(env: &Env, admin: &Address) {
9090
env.events()
9191
.publish((symbol_short!("unpause"),), (admin.clone(),));
9292
}
93+
94+
/// Emitted when the contract is upgraded.
95+
pub fn emit_upgrade(env: &Env, admin: &Address, new_wasm_hash: &BytesN<32>) {
96+
env.events().publish(
97+
(symbol_short!("upgrade"),),
98+
(admin.clone(), new_wasm_hash.clone()),
99+
);
100+
}
101+
102+
/// Emitted when the token name is updated.
103+
pub fn emit_update_name(env: &Env, admin: &Address, old_name: &String, new_name: &String) {
104+
env.events().publish(
105+
(symbol_short!("upd_name"),),
106+
(admin.clone(), old_name.clone(), new_name.clone()),
107+
);
108+
}
109+
110+
/// Emitted when the token symbol is updated.
111+
pub fn emit_update_symbol(env: &Env, admin: &Address, old_symbol: &String, new_symbol: &String) {
112+
env.events().publish(
113+
(symbol_short!("upd_sym"),),
114+
(admin.clone(), old_symbol.clone(), new_symbol.clone()),
115+
);
116+
}

contracts/token/src/lib.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ mod events;
1818
mod test;
1919

2020
use soroban_sdk::token::TokenInterface;
21-
use soroban_sdk::{contract, contractimpl, contracttype, Address, Env, String};
21+
use soroban_sdk::{contract, contractimpl, contracttype, Address, BytesN, Env, String};
2222

2323
/// Storage keys for the token contract state.
2424
#[derive(Clone)]
@@ -214,10 +214,47 @@ impl BcForgeToken {
214214
events::emit_unpaused(&env, &admin);
215215
}
216216

217+
/// Upgrades the contract to a new WASM hash. Admin-only.
218+
pub fn upgrade(env: Env, new_wasm_hash: BytesN<32>) {
219+
let admin = Self::read_admin(&env);
220+
admin.require_auth();
221+
222+
env.deployer().update_current_contract_wasm(new_wasm_hash.clone());
223+
events::emit_upgrade(&env, &admin, &new_wasm_hash);
224+
}
225+
217226
/// Returns the contract version.
218227
pub fn version(env: Env) -> String {
219228
String::from_str(&env, "1.0.0")
220229
}
230+
231+
/// Updates the token name. Admin-only.
232+
pub fn update_name(env: Env, new_name: String) {
233+
let admin = Self::read_admin(&env);
234+
admin.require_auth();
235+
236+
let old_name = env.storage()
237+
.instance()
238+
.get(&DataKey::Name)
239+
.unwrap_or_else(|| String::from_str(&env, "bc-forge"));
240+
241+
env.storage().instance().set(&DataKey::Name, &new_name);
242+
events::emit_update_name(&env, &admin, &old_name, &new_name);
243+
}
244+
245+
/// Updates the token symbol. Admin-only.
246+
pub fn update_symbol(env: Env, new_symbol: String) {
247+
let admin = Self::read_admin(&env);
248+
admin.require_auth();
249+
250+
let old_symbol = env.storage()
251+
.instance()
252+
.get(&DataKey::Symbol)
253+
.unwrap_or_else(|| String::from_str(&env, "SFG"));
254+
255+
env.storage().instance().set(&DataKey::Symbol, &new_symbol);
256+
events::emit_update_symbol(&env, &admin, &old_symbol, &new_symbol);
257+
}
221258
}
222259

223260
// ─────────────────────────────────────────────────────────────────────────────

sdk/src/client.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
stringToScVal,
1616
u32ToScVal,
1717
scValToNative,
18+
hashToScVal,
1819
} from './utils';
1920

2021
// ─── Types ───────────────────────────────────────────────────────────────────
@@ -272,6 +273,42 @@ export class bcForgeClient {
272273
return this.invokeContract('unpause', [], source);
273274
}
274275

276+
/**
277+
* Upgrades the contract to a new WASM hash. Admin-only.
278+
*
279+
* @param newWasmHash - 32-byte hex string or Buffer of the new WASM hash
280+
* @param source - Admin keypair
281+
*/
282+
async upgrade(newWasmHash: string | Buffer, source: Keypair): Promise<TransactionResult> {
283+
return this.invokeContract('upgrade', [
284+
hashToScVal(newWasmHash),
285+
], source);
286+
}
287+
288+
/**
289+
* Update the token name. Admin-only.
290+
*
291+
* @param newName - The new token name
292+
* @param source - Admin keypair
293+
*/
294+
async updateName(newName: string, source: Keypair): Promise<TransactionResult> {
295+
return this.invokeContract('update_name', [
296+
stringToScVal(newName),
297+
], source);
298+
}
299+
300+
/**
301+
* Update the token symbol. Admin-only.
302+
*
303+
* @param newSymbol - The new token symbol
304+
* @param source - Admin keypair
305+
*/
306+
async updateSymbol(newSymbol: string, source: Keypair): Promise<TransactionResult> {
307+
return this.invokeContract('update_symbol', [
308+
stringToScVal(newSymbol),
309+
], source);
310+
}
311+
275312
// ─── Internal Helpers ────────────────────────────────────────────────────
276313

277314
/**

sdk/src/utils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,12 @@ export function u32ToScVal(value: number): xdr.ScVal {
134134
export function scValToNative(scVal: xdr.ScVal): any {
135135
return sdkScValToNative(scVal);
136136
}
137+
138+
/**
139+
* Converts a 32-byte hex string or Buffer to an ScVal.
140+
*/
141+
export function hashToScVal(hash: string | Buffer): xdr.ScVal {
142+
const buf = typeof hash === 'string' ? Buffer.from(hash, 'hex') : hash;
143+
if (buf.length !== 32) throw new Error('Hash must be exactly 32 bytes');
144+
return xdr.ScVal.scvBytes(buf);
145+
}

0 commit comments

Comments
 (0)